Setup

We will clean the environment, setup the locations, define colors, and create a datestamp.

Clean the environment.

Set locations and working directories…


Create a new analysis directory...
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] FALSE
[1] "/Volumes/LaCie/PLINK/analyses/lookups/AE_20200512_COL_MKAVOUSI_MBOS_CHARGE_1000G_CAC"
 [1] "_archived"                                              "20211005.CAC.GWASSumStats.RData"                        "20211130.AERNA.results.RData"                          
 [4] "20211130.AESCRNA.scrnaseq_results.RData"                "AE_20200512_COL_MKAVOUSI_MBOS_CHARGE_1000G_CAC.nb.html" "AE_20200512_COL_MKAVOUSI_MBOS_CHARGE_1000G_CAC.Rmd"    
 [7] "AE_20200512_COL_MKAVOUSI_MBOS_CHARGE_1000G_CAC.Rproj"   "bulkRNAseq"                                             "CAC"                                                   
[10] "CredibleSets"                                           "LICENSE"                                                "Parsing_GWASSumStats.nb.html"                          
[13] "Parsing_GWASSumStats.Rmd"                               "README.html"                                            "README.md"                                             
[16] "scRNAseq"                                               "SNP"                                                    "WGCNA"                                                 

… a package-installation function …

install.packages.auto <- function(x) { 
  x <- as.character(substitute(x)) 
  if(isTRUE(x %in% .packages(all.available = TRUE))) { 
    eval(parse(text = sprintf("require(\"%s\")", x)))
  } else { 
    # Update installed packages - this may mean a full upgrade of R, which in turn
    # may not be warrented. 
    #update.install.packages.auto(ask = FALSE) 
    eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE, repos = \"https://cloud.r-project.org/\")", x)))
  }
  if(isTRUE(x %in% .packages(all.available = TRUE))) { 
    eval(parse(text = sprintf("require(\"%s\")", x)))
  } else {
    if (!requireNamespace("BiocManager"))
      install.packages("BiocManager")
    BiocManager::install() # this would entail updating installed packages, which in turned may not be warrented
    
    # Code for older versions of R (<3.5.0)
    # source("http://bioconductor.org/biocLite.R")
    # Update installed packages - this may mean a full upgrade of R, which in turn
    # may not be warrented.
    # biocLite(character(), ask = FALSE) 
    eval(parse(text = sprintf("BiocManager::install(\"%s\")", x)))
    eval(parse(text = sprintf("require(\"%s\")", x)))
  }
}

… and load those packages.

install.packages.auto("readr")
Loading required package: readr
install.packages.auto("optparse")
Loading required package: optparse
install.packages.auto("tools")
Loading required package: tools
install.packages.auto("dplyr")
Loading required package: dplyr

Attaching package: 'dplyr'

The following objects are masked from 'package:stats':

    filter, lag

The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
install.packages.auto("tidyr")
Loading required package: tidyr
install.packages.auto("naniar")
Loading required package: naniar
# To get 'data.table' with 'fwrite' to be able to directly write gzipped-files
# Ref: https://stackoverflow.com/questions/42788401/is-possible-to-use-fwrite-from-data-table-with-gzfile
# install.packages("data.table", repos = "https://Rdatatable.gitlab.io/data.table")
library(data.table)
data.table 1.14.2 using 1 threads (see ?getDTthreads).  Latest news: r-datatable.com
**********
This installation of data.table has not detected OpenMP support. It should still work but in single-threaded mode.
This is a Mac. Please read https://mac.r-project.org/openmp/. Please engage with Apple and ask them for support. Check r-datatable.com for updates, and our Mac instructions here: https://github.com/Rdatatable/data.table/wiki/Installation. After several years of many reports of installation problems on Mac, it's time to gingerly point out that there have been no similar problems on Windows or Linux.
**********

Attaching package: 'data.table'

The following objects are masked from 'package:dplyr':

    between, first, last
install.packages.auto("tidyverse")
Loading required package: tidyverse
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✓ ggplot2 3.3.5     ✓ stringr 1.4.0
✓ tibble  3.1.6     ✓ forcats 0.5.1
✓ purrr   0.3.4     
── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x data.table::between() masks dplyr::between()
x dplyr::filter()       masks stats::filter()
x data.table::first()   masks dplyr::first()
x dplyr::lag()          masks stats::lag()
x data.table::last()    masks dplyr::last()
x purrr::transpose()    masks data.table::transpose()
install.packages.auto("knitr")
Loading required package: knitr
install.packages.auto("DT")
Loading required package: DT
install.packages.auto("eeptools")
Loading required package: eeptools
Welcome to eeptools for R version 1.2.0!
Developed by Jared E. Knowles 2012-2018
for the Wisconsin Department of Public Instruction
Distributed without warranty.
install.packages.auto("haven")
Loading required package: haven
install.packages.auto("tableone")
Loading required package: tableone
install.packages.auto("BlandAltmanLeh")
Loading required package: BlandAltmanLeh
# Install the devtools package from Hadley Wickham
install.packages.auto('devtools')
Loading required package: devtools
Loading required package: usethis
# for plotting
install.packages.auto("pheatmap")
Loading required package: pheatmap
install.packages.auto("forestplot")
Loading required package: forestplot
Loading required package: grid
Loading required package: magrittr

Attaching package: 'magrittr'

The following object is masked from 'package:purrr':

    set_names

The following object is masked from 'package:tidyr':

    extract

Loading required package: checkmate
install.packages.auto("ggplot2")

install.packages.auto("ggpubr")
Loading required package: ggpubr
install.packages.auto("UpSetR")
Loading required package: UpSetR
devtools::install_github("thomasp85/patchwork")
Downloading GitHub repo thomasp85/patchwork@HEAD
These packages have more recent versions available.
It is recommended to update all of them.
Which would you like to update?

1: All                             
2: CRAN packages only              
3: None                            
4: glue   (1.5.0  -> 1.5.1 ) [CRAN]
5: withr  (2.4.2  -> 2.4.3 ) [CRAN]
6: digest (0.6.28 -> 0.6.29) [CRAN]

  
   checking for file ‘/private/var/folders/y3/46z02d352fq9jjzq_5jjt1vh0000gn/T/Rtmpm9Dwwe/remotescf0b1397ad49/thomasp85-patchwork-79223d3/DESCRIPTION’ ...
  
✓  checking for file ‘/private/var/folders/y3/46z02d352fq9jjzq_5jjt1vh0000gn/T/Rtmpm9Dwwe/remotescf0b1397ad49/thomasp85-patchwork-79223d3/DESCRIPTION’ (375ms)

  
─  preparing ‘patchwork’:

  
   checking DESCRIPTION meta-information ...
  
✓  checking DESCRIPTION meta-information

  
─  checking for LF line-endings in source and make files and shell scripts

  
─  checking for empty or unneeded directories
   Omitted ‘LazyData’ from DESCRIPTION

  
─  building ‘patchwork_1.1.0.9000.tar.gz’

  
   
Installing package into '/Users/slaan3/Library/R/x86_64/4.1/library'
(as 'lib' is unspecified)
* installing *source* package ‘patchwork’ ...
** using staged installation
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
*** copying figures
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (patchwork)

We will create a datestamp and define the Utrecht Science Park Colour Scheme.


Today = format(as.Date(as.POSIXlt(Sys.time())), "%Y%m%d")
Today.Report = format(as.Date(as.POSIXlt(Sys.time())), "%A, %B %d, %Y")

### UtrechtScienceParkColoursScheme
###
### WebsitetoconvertHEXtoRGB:http://hex.colorrrs.com.
### Forsomefunctionsyoushoulddividethesenumbersby255.
###
### No. Color                 HEX   (RGB)                                     CHR         MAF/INFO
###---------------------------------------------------------------------------------------
### 1     yellow                #FBB820 (251,184,32)                      =>    1       or 1.0>INFO
### 2     gold                #F59D10 (245,157,16)                    =>    2       
### 3     salmon                #E55738 (229,87,56)                   =>    3       or 0.05<MAF<0.2 or 0.4<INFO<0.6
### 4     darkpink          #DB003F ((219,0,63)                   =>    4       
### 5     lightpink         #E35493 (227,84,147)                      =>    5       or 0.8<INFO<1.0
### 6     pink                #D5267B (213,38,123)                    =>    6       
### 7     hardpink          #CC0071 (204,0,113)                   =>    7       
### 8     lightpurple       #A8448A (168,68,138)                      =>    8       
### 9     purple                #9A3480 (154,52,128)                      =>    9       
### 10  lavendel            #8D5B9A (141,91,154)                      =>    10      
### 11  bluepurple        #705296 (112,82,150)                    =>    11      
### 12  purpleblue        #686AA9 (104,106,169)               =>    12      
### 13  lightpurpleblue #6173AD (97,115,173/101,120,180)    =>  13      
### 14  seablue             #4C81BF (76,129,191)                      =>    14      
### 15  skyblue             #2F8BC9 (47,139,201)                      =>    15      
### 16  azurblue            #1290D9 (18,144,217)                      =>    16      or 0.01<MAF<0.05 or 0.2<INFO<0.4
### 17  lightazurblue     #1396D8 (19,150,216)                    =>    17      
### 18  greenblue           #15A6C1 (21,166,193)                      =>    18      
### 19  seaweedgreen      #5EB17F (94,177,127)                    =>    19      
### 20  yellowgreen       #86B833 (134,184,51)                    =>    20      
### 21  lightmossgreen  #C5D220 (197,210,32)                      =>    21      
### 22  mossgreen           #9FC228 (159,194,40)                      =>    22      or MAF>0.20 or 0.6<INFO<0.8
### 23  lightgreen      #78B113 (120,177,19)                      =>    23/X
### 24  green                 #49A01D (73,160,29)                     =>    24/Y
### 25  grey                  #595A5C (89,90,92)                        =>  25/XY   or MAF<0.01 or 0.0<INFO<0.2
### 26  lightgrey           #A2A3A4 (162,163,164)                 =>    26/MT
###
### ADDITIONAL COLORS
### 27  midgrey         #D7D8D7
### 28  verylightgrey   #ECECEC"
### 29  white           #FFFFFF
### 30  black           #000000
###----------------------------------------------------------------------------------------------

uithof_color = c("#FBB820","#F59D10","#E55738","#DB003F","#E35493","#D5267B",
                 "#CC0071","#A8448A","#9A3480","#8D5B9A","#705296","#686AA9",
                 "#6173AD","#4C81BF","#2F8BC9","#1290D9","#1396D8","#15A6C1",
                 "#5EB17F","#86B833","#C5D220","#9FC228","#78B113","#49A01D",
                 "#595A5C","#A2A3A4", "#D7D8D7", "#ECECEC", "#FFFFFF", "#000000")

uithof_color_legend = c("#FBB820", "#F59D10", "#E55738", "#DB003F", "#E35493",
                        "#D5267B", "#CC0071", "#A8448A", "#9A3480", "#8D5B9A",
                        "#705296", "#686AA9", "#6173AD", "#4C81BF", "#2F8BC9",
                        "#1290D9", "#1396D8", "#15A6C1", "#5EB17F", "#86B833",
                        "#C5D220", "#9FC228", "#78B113", "#49A01D", "#595A5C",
                        "#A2A3A4", "#D7D8D7", "#ECECEC", "#FFFFFF", "#000000")
### ----------------------------------------------------------------------------

Introduction

Project details

Collaborators

Maryam Kavousi, Patricia Peyser, Maxime Bos, Clint Miller

Project ID AE_20200512_COL_MKAVOUSI_MBOS_CHARGE_1000G_CAC

Background

Here we map the CHARGE Consortium 1000G GWAS on coronary artery calcification (CAC) susceptibility loci to the single-cell carotid plaque data. These are given in:

  • Variants.xlsx - sheet Variants, originally from IndSigSNPsforSander.xlsx
  • Genes.xlsx, originally from 20210127_Overview_Genes_MMBos_Sander.xlsx
  • Variants.xlsx - sheet CredibleSet, originally from 20210127_Overview_Genes_MMBos_Sander.xlsx
library(openxlsx)

# old list
# gene_list <- read.xlsx(paste0(TARGET_loc, "/GeneList_15042020.xlsx"))

# update list
gene_list <- read.xlsx(paste0(SNP_loc, "/Genes.xlsx"))

variant_list <- read.xlsx(paste0(SNP_loc, "/Variants.xlsx"), sheet = "Variants")
credset_list <- read.xlsx(paste0(SNP_loc, "/Variants.xlsx"), sheet = "CredibleSet")

DT::datatable(gene_list)

DT::datatable(variant_list)
DT::datatable(credset_list)
NA

We will construct a list of genes to map to our scRNAseq data.


target_genes <- unlist(gene_list$symbol)
target_genes
NULL

We will test the hypothesis that CAC susceptibility loci are associated with plaque characteristics. We will use data from the Athero-Express Biobank Study.

Study design

We will perform regression analyses adjusted for age, sex (where applicable) and principal components.

Modeling

We will apply the following models:

model 1: phenotype ~ age + sex + chip-used + PC1 + PC2 + year-of-surgery

phenotypes are:

  • calcification, coded Calc.bin no/minor vs. moderate/heavy staining
  • collagen, coded Collagen.bin no/minor vs. moderate/heavy staining
  • fat10, coded Fat.bin_10 no/<10% fat vs. >10% fat
  • fat40, coded Fat.bin_40 no/<40% fat vs. >40% fat
  • intraplaque hemorrhage, coded IPH.bin no vs. yes
  • macrophages (CD68), coded macmean0 mean of computer-assisted calculation CD68+ region of interest
  • smooth muscle cells (alpha-actin), coded smcmean0 mean of computer-assisted calculation SMA+ region of interest
  • intraplaque vessel density (CD34), coded vessel_density manually counted CD34+ cells per 3-4 hotspots
  • mast cells, coded Mast_cells_plaque manually counted mast cell tryptase+ cells (https://academic.oup.com/eurheartj/article/34/48/3699/484981)
  • neutrophils (CD66b), coded neutrophils manually counted CD66b+ cells (https://pubmed.ncbi.nlm.nih.gov/20595650/)

Athero-Express Biobank Study

The Athero-Express Biobank Study (AE) contains plaque material of patients that underwent endarterectomyat two Dutch tertiary referral centers. Details of the study design were described before. Briefly, blood and plaque material were obtained during endarterectomy and stored at -80 ℃. Only carotid endarterectomy (CEA) patients were included in the present study. All patients provided informed consent and the study was approved by the medical ethics committee.

Athero-Express Genomics Study

DNA isolation and genotyping

We genotyped the AE in three separate, but consecutive experiments. In short, DNA was extracted from EDTA blood or (when no blood was available) plaque samples of 1,858 consecutive patients from the Athero-Express Biobank Study and genotyped in 3 batches.

For the Athero-Express Genomics Study 1 (AEGS1) 891 patients (602 males, 262 females, 27 unknown sex), included between 2002 and 2007, were genotyped (440,763 markers) using the Affymetrix Genome-Wide Human SNP Array 5.0 (SNP5) chip (Affymetrix Inc., Santa Clara, CA, USA) at Eurofins Genomics (formerly known as AROS).

For the Athero-Express Genomics Study 2 (AEGS2) 954 patients (640 makes, 313 females, 1 unknown sex), included between 2002 and 2013, were genotyped (587,351 markers) using the Affymetrix AxiomⓇ GW CEU 1 Array (AxM) at the Genome Analysis Center.

For the Athero-Express Genomics Study 3 (AEGS3) 658 patients (448 males, 203 females, 5 unknown sex), included between 2002 and 2016, were genotyped (693,931 markers) using the Illumina GSA MD v1 BeadArray (GSA) at Human Genomics Facility, HUGE-F.

All experiments were carried out according to OECD standards.

Genotyping calling

We used the genotyping calling algorithms as advised by Affymetrix (AEGS1 and AEGS2) and Illumina (AEGS3):

  • AEGS1: BRLMM-P
  • AEGS2: AxiomGT1
  • AEGS3: Illumina GenomeStudio

Quality control after genotyping

After genotype calling, we adhered to community standard quality control and assurance (QCA) procedures of the genotype data from AEGS1, AEGS2, and AEGS3. Samples with low average genotype calling and sex discrepancies (compared to the clinical data available) were excluded. The data was further filtered on:

  1. individual (sample) call rate > 97%,
  2. SNP call rate > 97%,
  3. minor allele frequencies (MAF) > 3%,
  4. average heterozygosity rate ± 3.0 s.d.,
  5. relatedness (pi-hat > 0.20),
  6. Hardy–Weinberg Equilibrium (HWE p < 1.0×10−3<>), and
  7. Monomorphic SNPs (< 1.0×10−6<>).

After QCA 2,493 samples remained, 108 of non-European descent/ancestry, and 156 related pairs. These comprise 890 samples and 407,712 SNPs in AEGS1, 869 samples and 534,508 SNPs in AEGS2, and 649954 samples and 534,508 SNPs in AEGS3 remained.

Imputation

Before phasing using SHAPEIT2, data was lifted to genome build b37 using the liftOver tool from UCSC (https://genome.ucsc.edu/cgi-bin/hgLiftOver). Finally, data was imputed with 1000G phase 3, version 5 and HRC release 1.1 as a reference using the Michigan Imputation Server. These results were further integrated using QCTOOL v2, where HRC imputed variants are given precendence over 1000G phase 3 imputed variants.

Quality control after imputation

We compared quality of the three AEGS datasets, and listed some variables of interest.

  • sample type (EDTA blood or plaque)
  • genotyping chip used
  • reason for filtering

We checked the studytype (AE or not), and identity-by-descent (IBD) within and between datasets to aid in sample mixups, duplicate sample use, and relatedness. In addition, during genotyping quality control samples were identified that deviated from Hardy-Weinberg Equilibrium (HWE), had discordance in sex-coding and genotype sex, and deviated from the principal component analysis (PCA) plot.

We will load the Athero-Express Biobank Study data, and all the samples that were send for genotyping and the final QC’ed sampleList.

Loading data

Loading Athero-Express Biobank Study clinical and biobank data, as well as the SampleList of genetic data.

cat("* get Athero-Express Biobank Study Database...")
* get Athero-Express Biobank Study Database...
# METHOD 1: It seems this method gives loads of errors and warnings, which all are hard to comprehend
#           or debug. We expect 3,527 samples, and 927 variables; we get 927 variables!!!
# AEdata = as.data.table(read.spss(paste0(INP_loc,"/2017-1NEW_AtheroExpressDatabase_ScientificAE_20171306_v1.0.sav"),
#                                  trim.factor.names = TRUE, trim_values = TRUE, # we trim spaces in values
#                                  reencode = TRUE, # we re-encode to the local locale encoding
#                                  add.undeclared.levels = "append", # we do *not* want to convert to R-factors
#                                  use.value.labels = FALSE, # we do *not* convert variables with value labels into R factors
#                                  use.missings = TRUE, sub = "NA", # we will set every missing variable to NA
#                                  duplicated.value.labels = "condense", # we will condense duplicated value labels
#                                  to.data.frame = TRUE))
# AEdata.labels <- as.data.table(attr(AEdata, "variable.labels"))
# names(AEdata.labels) <- "Variable"

# METHOD 2: Using library("haven") importing seems flawless; best argument being:
#           we expect 3,527 samples and 888 variables, which is what you'd get with this method
#           So for now, METHOD 2 is prefered. 
#            
require(haven)

# AEDB <- haven::read_sav(paste0(AEDB_loc, "/2019-3NEW_AtheroExpressDatabase_ScientificAE_02072019_IC_added.sav"))
AEDB <- haven::read_sav(paste0(AEDB_loc, "/2020_1_NEW_AtheroExpressDatabase_ScientificAE_16-03-2020.sav"))

# writing off the SPSS data to an Excel.
# fwrite(AEdata, file = paste0(INP_loc,"/2017-1NEW_AtheroExpressDatabase_ScientificAE_20171306_v1.0.values.xlsx"), 
#        sep = ";", na = "NA", dec = ".", col.names = TRUE, row.names = FALSE,
#        dateTimeAs = "ISO", showProgress = TRUE, verbose = TRUE)
# warnings()

AEDB[1:10, 1:10]
dim(AEDB)
[1] 3791 1091
cat("* get Athero-Express Genomics Study keys...")
* get Athero-Express Genomics Study keys...
AEGS123.sampleList.keytable <- fread(paste0(AEGSQC_loc, "/QC/SELECTIONS/20200319.QC.AEGS123.sampleList.keytable.txt"))

dim(AEGS123.sampleList.keytable)
[1] 2124   25
# AEGS123.sampleList.keytable[1:10, 1:10]

Examine AEDB

We can examine the contents of the Athero-Express Biobank dataset to know what each variable is called, what class (type) it has, and what the variable description is.

There is an excellent post on this: https://www.r-bloggers.com/working-with-spss-labels-in-r/.

AEDB %>% sjPlot::view_df(show.type = TRUE,
                         show.frq = TRUE,
                         show.prc = TRUE,
                         show.na = TRUE, 
                         max.len = TRUE, 
                         wrap.labels = 20,
                         verbose = FALSE, 
                         use.viewer = FALSE,
                         file = paste0(OUT_loc, "/", Today, ".AEDB.dictionary.html")) 
Following 3 variables have only missing values and are not shown:
yearpsy5 [326], yearchol3 [347], yearablo3 [419]
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation

Fix clinical data

We need to be very strict in defining symptoms. Therefore we will fix a new variable that groups symptoms at inclusion.

Coding of symptoms is as follows:

  • missing -999
  • Asymptomatic 0
  • TIA 1
  • minor stroke 2
  • Major stroke 3
  • Amaurosis fugax 4
  • Four vessel disease 5
  • Vertebrobasilary TIA 7
  • Retinal infarction 8
  • Symptomatic, but aspecific symtoms 9
  • Contralateral symptomatic occlusion 10
  • retinal infarction 11
  • armclaudication due to occlusion subclavian artery, CEA needed for bypass 12
  • retinal infarction + TIAs 13
  • Ocular ischemic syndrome 14
  • ischemisch glaucoom 15
  • subclavian steal syndrome 16
  • TGA 17

We will group as follows:

  1. Asymptomatic > 0
  2. TIA > 1, 7, 13
  3. Stroke > 2, 3
  4. Ocular > 4, 14, 15
  5. Retinal infarction > 8, 11
  6. Other > 5, 9, 10, 12, 16, 17

# Fix symptoms

attach(AEDB)
AEDB[,"Symptoms.5G"] <- NA
AEDB$Symptoms.5G[sympt == 0] <- "Asymptomatic"
AEDB$Symptoms.5G[sympt == 1 | sympt == 7 | sympt == 13] <- "TIA"
AEDB$Symptoms.5G[sympt == 2 | sympt == 3] <- "Stroke"
AEDB$Symptoms.5G[sympt == 4 | sympt == 14 | sympt == 15 ] <- "Ocular"
AEDB$Symptoms.5G[sympt == 8 | sympt == 11] <- "Retinal infarction"
AEDB$Symptoms.5G[sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Other"


# AsymptSympt
AEDB[,"AsymptSympt"] <- NA
AEDB$AsymptSympt[sympt == -999] <- NA
AEDB$AsymptSympt[sympt == 0] <- "Asymptomatic"
AEDB$AsymptSympt[sympt == 1 | sympt == 7 | sympt == 13 | sympt == 2 | sympt == 3] <- "Symptomatic"
AEDB$AsymptSympt[sympt == 4 | sympt == 14 | sympt == 15 | sympt == 8 | sympt == 11 | sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Ocular and others"

# AsymptSympt
AEDB[,"AsymptSympt2G"] <- NA
AEDB$AsymptSympt2G[sympt == -999] <- NA
AEDB$AsymptSympt2G[sympt == 0] <- "Asymptomatic"
AEDB$AsymptSympt2G[sympt == 1 | sympt == 7 | sympt == 13 | sympt == 2 | sympt == 3 | sympt == 4 | sympt == 14 | sympt == 15 | sympt == 8 | sympt == 11 | sympt == 5 | sympt == 9 | sympt == 10 | sympt == 12 | sympt == 16 | sympt == 17] <- "Symptomatic"

detach(AEDB)

# table(AEDB$sympt, useNA = "ifany")
# table(AEDB$AsymptSympt2G, useNA = "ifany")
# table(AEDB$Symptoms.5G, useNA = "ifany")
# 
# table(AEDB$AsymptSympt2G, AEDB$sympt, useNA = "ifany")
# table(AEDB$Symptoms.5G, AEDB$sympt, useNA = "ifany")
table(AEDB$AsymptSympt2G, AEDB$Symptoms.5G, useNA = "ifany")
              
               Asymptomatic Ocular Other Retinal infarction Stroke  TIA <NA>
  Asymptomatic          333      0     0                  0      0    0    0
  Symptomatic             0    416   119                 43    732 1045    0
  <NA>                    0      0     0                  0      0    0 1103
# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "sympt", "Symptoms.5G", "AsymptSympt"))
# require(labelled)
# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
# 
# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
# 
# table(AEDB.temp$Symptoms.5G, AEDB.temp$AsymptSympt)
# 
# rm(AEDB.temp)

We will also fix the plaquephenotypes variable.

Coding of symptoms is as follows:

  • missing -999
  • not relevant -888
  • fibrous 1
  • fibroatheromatous 2
  • atheromatous 3

# Fix plaquephenotypes
attach(AEDB)
AEDB[,"OverallPlaquePhenotype"] <- NA
AEDB$OverallPlaquePhenotype[plaquephenotype == -999] <- NA
AEDB$OverallPlaquePhenotype[plaquephenotype == -999] <- NA
AEDB$OverallPlaquePhenotype[plaquephenotype == 1] <- "fibrous"
AEDB$OverallPlaquePhenotype[plaquephenotype == 2] <- "fibroatheromatous"
AEDB$OverallPlaquePhenotype[plaquephenotype == 3] <- "atheromatous"
detach(AEDB)

# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "plaquephenotype", "OverallPlaquePhenotype"))
# require(labelled)
# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
# 
# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
# 
# rm(AEDB.temp)

We will also fix the diabetes status variable.


# Fix diabetes
attach(AEDB)
AEDB[,"DiabetesStatus"] <- NA
AEDB$DiabetesStatus[DM.composite == -999] <- NA
AEDB$DiabetesStatus[DM.composite == 0] <- "Control (no Diabetes Dx/Med)"
AEDB$DiabetesStatus[DM.composite == 1] <- "Diabetes"
detach(AEDB)

# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "DM.composite", "DiabetesStatus"))
# require(labelled)
# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
# AEDB.temp$DiabetesStatus <- to_factor(AEDB.temp$DiabetesStatus)
# 
# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
# 
# rm(AEDB.temp)

We will also fix the smoking status variable. We are interested in whether someone never, ever or is currently (at the time of inclusion) smoking. This is based on the questionnaire.

  • diet801: are you a smoker?
  • diet802: did you smoke in the past?

We already have some variables indicating smoking status:

  • SmokingReported: patient has reported to smoke.
  • SmokingYearOR: smoking in the year of surgery?
  • SmokerCurrent: currently smoking?
require(labelled)
Loading required package: labelled
AEDB$diet801 <- to_factor(AEDB$diet801)
AEDB$diet802 <- to_factor(AEDB$diet802)
AEDB$diet805 <- to_factor(AEDB$diet805)
AEDB$SmokingReported <- to_factor(AEDB$SmokingReported)
AEDB$SmokerCurrent <- to_factor(AEDB$SmokerCurrent)
AEDB$SmokingYearOR <- to_factor(AEDB$SmokingYearOR)

# table(AEDB$diet801)
# table(AEDB$diet802)
# table(AEDB$SmokingReported)
# table(AEDB$SmokerCurrent)
# table(AEDB$SmokingYearOR)
# table(AEDB$SmokingReported, AEDB$SmokerCurrent, useNA = "ifany", dnn = c("Reported smoking", "Current smoker"))
# 
# table(AEDB$diet801, AEDB$diet802, useNA = "ifany", dnn = c("Smoker", "Past smoker"))

cat("\nFixing smoking status.\n")

Fixing smoking status.
attach(AEDB)
AEDB[,"SmokerStatus"] <- NA
AEDB$SmokerStatus[diet802 == "don't know"] <- "Never smoked"
AEDB$SmokerStatus[diet802 == "I still smoke"] <- "Current smoker"
AEDB$SmokerStatus[SmokerCurrent == "no" & diet802 == "no"] <- "Never smoked"
AEDB$SmokerStatus[SmokerCurrent == "no" & diet802 == "yes"] <- "Ex-smoker"
AEDB$SmokerStatus[SmokerCurrent == "yes"] <- "Current smoker"
AEDB$SmokerStatus[SmokerCurrent == "no data available/missing"] <- NA
# AEDB$SmokerStatus[is.na(SmokerCurrent)] <- "Never smoked"
detach(AEDB)

cat("\n* Current smoking status.\n")

* Current smoking status.
table(AEDB$SmokerCurrent,
      useNA = "ifany", 
      dnn = c("Current smoker"))
Current smoker
no data available/missing                        no                       yes                      <NA> 
                        0                      2364                      1308                       119 
cat("\n* Updated smoking status.\n")

* Updated smoking status.
table(AEDB$SmokerStatus,
      useNA = "ifany", 
      dnn = c("Updated smoking status"))
Updated smoking status
Current smoker      Ex-smoker   Never smoked           <NA> 
          1308           1814            389            280 
cat("\n* Comparing to 'SmokerCurrent'.\n")

* Comparing to 'SmokerCurrent'.
table(AEDB$SmokerStatus, AEDB$SmokerCurrent, 
      useNA = "ifany", 
      dnn = c("Updated smoking status", "Current smoker"))
                      Current smoker
Updated smoking status no data available/missing   no  yes <NA>
        Current smoker                         0    0 1308    0
        Ex-smoker                              0 1814    0    0
        Never smoked                           0  389    0    0
        <NA>                                   0  161    0  119
# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "DM.composite", "DiabetesStatus"))
# require(labelled)
# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
# AEDB.temp$DiabetesStatus <- to_factor(AEDB.temp$DiabetesStatus)
# 
# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
# 
# rm(AEDB.temp)

We will also fix the alcohol status variable.


# Fix diabetes
attach(AEDB)
AEDB[,"AlcoholUse"] <- NA
AEDB$AlcoholUse[diet810 == -999] <- NA
AEDB$AlcoholUse[diet810 == 0] <- "No"
AEDB$AlcoholUse[diet810 == 1] <- "Yes"
detach(AEDB)

# AEDB.temp <- subset(AEDB,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "diet810", "AlcoholUse"))
# require(labelled)
# AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
# AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
# AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
# AEDB.temp$AlcoholUse <- to_factor(AEDB.temp$AlcoholUse)
# 
# DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)
# 
# rm(AEDB.temp)

We will also fix and inverse-rank normal transform the continuous (manually) scored plaque phenotypes.

AEDB$macmean0 <- as.numeric(AEDB$macmean0)
AEDB$smcmean0 <- as.numeric(AEDB$smcmean0)
AEDB$neutrophils <- as.numeric(AEDB$neutrophils)
AEDB$Mast_cells_plaque <- as.numeric(AEDB$Mast_cells_plaque)
AEDB$vessel_density_averaged <- as.numeric(AEDB$vessel_density_averaged)

AEDB$MAC_rankNorm <- qnorm((rank(AEDB$macmean0, na.last = "keep") - 0.5) / sum(!is.na(AEDB$macmean0)))
AEDB$SMC_rankNorm <- qnorm((rank(AEDB$smcmean0, na.last = "keep") - 0.5) / sum(!is.na(AEDB$smcmean0)))
AEDB$Neutrophils_rankNorm <- qnorm((rank(AEDB$neutrophils, na.last = "keep") - 0.5) / sum(!is.na(AEDB$neutrophils)))
AEDB$MastCells_rankNorm <- qnorm((rank(AEDB$Mast_cells_plaque, na.last = "keep") - 0.5) / sum(!is.na(AEDB$Mast_cells_plaque)))
AEDB$VesselDensity_rankNorm <- qnorm((rank(AEDB$vessel_density_averaged, na.last = "keep") - 0.5) / sum(!is.na(AEDB$vessel_density_averaged)))
library(labelled)
AEDB$Gender <- to_factor(AEDB$Gender)
ggpubr::gghistogram(AEDB, "macmean0", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "% of macrophages (CD68)",
                    xlab = "% per region of interest", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 1228 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "MAC_rankNorm", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "% of macrophages (CD68)",
                   xlab = "% per region of interest\ninverse-rank normalized number", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 1228 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "smcmean0", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "% of smooth muscle cells (SMA)",
                    xlab = "% per region of interest", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 1230 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "SMC_rankNorm", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "% of smooth muscle cells (SMA)",
                   xlab = "% per region of interest\ninverse-rank normalized number", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 1230 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "neutrophils", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "number of neutrophils (CD66b)",
                    xlab = "counts per plaque", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 3450 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "Neutrophils_rankNorm", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "number of neutrophils (CD66b)",
                   xlab = "counts per plaque\ninverse-rank normalized number", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 3450 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "Mast_cells_plaque", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "number of mast cells",
                    xlab = "counts per plaque", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 3527 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "MastCells_rankNorm", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "number of mast cells",
                   xlab = "counts per plaque\ninverse-rank normalized number", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 3527 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "vessel_density_averaged", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "number of intraplaque neovessels",
                    xlab = "counts per 3-4 hotspots", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 1821 rows containing non-finite values (stat_bin).

ggpubr::gghistogram(AEDB, "VesselDensity_rankNorm", 
                    # y = "..count..", 
                    color = "white",
                    fill = "Gender",
                    palette = c("#1290D9", "#DB003F"), 
                    add = "median", 
                    #add_density = TRUE,
                    rug = TRUE,
                    #add.params =  list(color = "black", linetype = 2), 
                    title = "number of intraplaque neovessels",
                   xlab = "counts per 3-4 hotspots\ninverse-rank normalized number", 
                    ggtheme = theme_minimal())
Warning: Using `bins = 30` by default. Pick better value with the argument `bins`.
Warning: Removed 1821 rows containing non-finite values (stat_bin).

Here we calculate the plaque instability/vulnerability index


# Plaque vulnerability

# SPSS code

# 
# *** syntax- Plaque vulnerability**.
# COMPUTE Macro_instab = -999.
# IF macrophages.bin=2 Macro_instab=1.
# IF macrophages.bin=1 Macro_instab=0.
# EXECUTE.
# 
# COMPUTE Fat10_instab = -999.
# IF Fat.bin_10=2 Fat10_instab=1.
# IF Fat.bin_10=1 Fat10_instab=0.
# EXECUTE.
# 
# COMPUTE coll_instab=-999.
# IF Collagen.bin=2 coll_instab=0.
# IF Collagen.bin=1 coll_instab=1.
# EXECUTE.
# 
# 
# COMPUTE SMC_instab=-999.
# IF SMC.bin=2 SMC_instab=0.
# IF SMC.bin=1 SMC_instab=1.
# EXECUTE.
# 
# COMPUTE IPH_instab=-999.
# IF IPH.bin=0 IPH_instab=0.
# IF IPH.bin=1 IPH_instab=1.
# EXECUTE.
# 
# COMPUTE Instability=Macro_instab + Fat10_instab +  coll_instab + SMC_instab + IPH_instab.
# EXECUTE.

require(labelled)
AEDB$Macrophages.bin <- to_factor(AEDB$Macrophages.bin)
AEDB$SMC.bin <- to_factor(AEDB$SMC.bin)
AEDB$IPH.bin <- to_factor(AEDB$IPH.bin)
AEDB$Calc.bin <- to_factor(AEDB$Calc.bin)
AEDB$Collagen.bin <- to_factor(AEDB$Collagen.bin)
AEDB$Fat.bin_10 <- to_factor(AEDB$Fat.bin_10)
AEDB$Fat.bin_40 <- to_factor(AEDB$Fat.bin_40)

table(AEDB$Macrophages.bin)

      no/minor moderate/heavy 
          1602           1215 
table(AEDB$Fat.bin_10)

 <10%  >10% 
 1226  1628 
table(AEDB$Collagen.bin)

      no/minor moderate/heavy 
           540           2297 
table(AEDB$SMC.bin)

      no/minor moderate/heavy 
           870           1962 
table(AEDB$IPH.bin)

  no  yes 
1223 1628 
# Fix plaquephenotypes
attach(AEDB)
# mac instability
AEDB[,"MAC_Instability"] <- NA
AEDB$MAC_Instability[Macrophages.bin == -999] <- NA
AEDB$MAC_Instability[Macrophages.bin == "no/minor"] <- 0
AEDB$MAC_Instability[Macrophages.bin == "moderate/heavy"] <- 1

# fat instability
AEDB[,"FAT10_Instability"] <- NA
AEDB$FAT10_Instability[Fat.bin_10 == -999] <- NA
AEDB$FAT10_Instability[Fat.bin_10 == " <10%"] <- 0
AEDB$FAT10_Instability[Fat.bin_10 == " >10%"] <- 1

# col instability 
AEDB[,"COL_Instability"] <- NA
AEDB$COL_Instability[Collagen.bin == -999] <- NA
AEDB$COL_Instability[Collagen.bin == "no/minor"] <- 1
AEDB$COL_Instability[Collagen.bin == "moderate/heavy"] <- 0

# smc instability
AEDB[,"SMC_Instability"] <- NA
AEDB$SMC_Instability[SMC.bin == -999] <- NA
AEDB$SMC_Instability[SMC.bin == "no/minor"] <- 1
AEDB$SMC_Instability[SMC.bin == "moderate/heavy"] <- 0

# iph instability
AEDB[,"IPH_Instability"] <- NA
AEDB$IPH_Instability[IPH.bin == -999] <- NA
AEDB$IPH_Instability[IPH.bin == "no"] <- 0
AEDB$IPH_Instability[IPH.bin == "yes"] <- 1

detach(AEDB)

table(AEDB$MAC_Instability, useNA = "ifany")

   0    1 <NA> 
1602 1215  974 
table(AEDB$FAT10_Instability, useNA = "ifany")

   0    1 <NA> 
1226 1628  937 
table(AEDB$COL_Instability, useNA = "ifany")

   0    1 <NA> 
2297  540  954 
table(AEDB$SMC_Instability, useNA = "ifany")

   0    1 <NA> 
1962  870  959 
table(AEDB$IPH_Instability, useNA = "ifany")

   0    1 <NA> 
1223 1628  940 
# creating vulnerability index
AEDB <- AEDB %>% mutate(Plaque_Vulnerability_Index = factor(rowSums(.[grep("_Instability", names(.))], na.rm = TRUE)),
                                )

table(AEDB$Plaque_Vulnerability_Index, useNA = "ifany")

   0    1    2    3    4    5 
1324  655  728  676  298  110 
# str(AEDB$Plaque_Vulnerability_Index)

Prepare baseline characteristics

We are interested in the following variables at baseline.

  • Age (years)
  • Female sex (N, %)
  • Hypertension (N, %)
  • SBP (mmHg)
  • DBP (mmHg)
  • Diabetes mellitus (N, %)
  • Total cholesterol levels (mg/dL)
  • LDL cholesterol levels (mg/dL)
  • HDL cholesterol levels (mg/dL)
  • Triglyceride levels (mg/dL)
  • Use of statins (N, %)
  • Use of antiplatelet drugs (N, %)
  • BMI (kg/m²)
  • Smoking status (N, %)
    • Never smokers
    • Ex-smokers
    • Current smokers
  • History of CAD (N, %)
  • History of PAD (N, %)
  • Clinical manifestations
    • Asymptomatic
    • Amaurosis fugax
    • TIA
    • Stroke
  • eGFR (mL/min/1.73 m²)
  • stenosis
  • year of surgery
  • plaque characteristics
cat("====================================================================================================\n")
====================================================================================================
cat("SELECTION THE SHIZZLE\n")
SELECTION THE SHIZZLE
### Artery levels
# AEdata$Artery_summary: 
#           value                                                                                   label
# NOT USE - 0 No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA
# USE - 1                                                                  carotid (left & right)
# USE - 2                                               femoral/iliac (left, right or both sides)
# NOT USE - 3                                               other carotid arteries (common, external)
# NOT USE - 4                                   carotid bypass and injury (left, right or both sides)
# NOT USE - 5                                                         aneurysmata (carotid & femoral)
# NOT USE - 6                                                                                   aorta
# NOT USE - 7                                            other arteries (renal, popliteal, vertebral)
# NOT USE - 8                        femoral bypass, angioseal and injury (left, right or both sides)

### AEdata$informedconsent
#           value                                                                                           label
# NOT USE - -999                                                                                         missing
# NOT USE - 0                                                                                        no, died
# USE - 1                                                                                             yes
# USE - 2                                                             yes, health treatment when possible
# USE - 3                                                                        yes, no health treatment
# USE - 4                                                yes, no health treatment, no commercial business
# NOT USE - 5                                                          yes, no tissue, no commerical business
# NOT USE - 6                      yes, no tissue, no questionnaires, no medical info, no commercial business
# USE - 7                             yes, no questionnaires, no health treatment, no commercial business
# USE - 8                                          yes, no questionnaires, health treatment when possible
# NOT USE - 9                  yes, no tissue, no questionnaires, no health treatment, no commerical business
# USE - 10                               yes, no health treatment, no medical info, no commercial business
# NOT USE - 11 yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business
# USE - 12                                                     yes, no questionnaires, no health treatment
# NOT USE - 13                                                             yes, no tissue, no health treatment
# NOT USE - 14                                                               yes, no tissue, no questionnaires
# NOT USE - 15                                                  yes, no tissue, health treatment when possible
# NOT USE - 16                                                                                  yes, no tissue
# USE - 17                                                                     yes, no commerical business
# USE - 18                                     yes, health treatment when possible, no commercial business
# USE - 19                                                    yes, no medical info, no commercial business
# USE - 20                                                                          yes, no questionnaires
# NOT USE - 21                         yes, no tissue, no questionnaires, no health treatment, no medical info
# NOT USE - 22                  yes, no tissue, no questionnaires, no health treatment, no commercial business
# USE - 23                                                                            yes, no medical info
# USE - 24                                                  yes, no questionnaires, no commercial business
# USE - 25                                    yes, no questionnaires, no health treatment, no medical info
# USE - 26                  yes, no questionnaires, health treatment when possible, no commercial business
# USE - 27                                                      yes,  no health treatment, no medical info
# NOT USE - 28                                                                             no, doesn't want to
# NOT USE - 29                                                                              no, unable to sign
# NOT USE - 30                                                                                 no, no reaction
# NOT USE - 31                                                                                        no, lost
# NOT USE - 32                                                                                     no, too old
# NOT USE - 34                                            yes, no medical info, health treatment when possible
# NOT USE - 35                                             no (never asked for IC because there was no tissue)
# USE - 36                    yes, no medical info, no commercial business, health treatment when possible
# NOT USE - 37                                                                                    no, endpoint
# USE - 38                                                         wil niets invullen, wel alles gebruiken
# USE - 39                                           second informed concents: yes, no commercial business
# NOT USE - 40                                                                              nooit geincludeerd

cat("- sanity checking PRIOR to selection")
- sanity checking PRIOR to selection
library(data.table)
require(labelled)
ae.gender <- to_factor(AEDB$Gender)
ae.hospital <- to_factor(AEDB$Hospital)
table(ae.gender, ae.hospital, dnn = c("Sex", "Hospital"))
        Hospital
Sex      St. Antonius, Nieuwegein UMC Utrecht
  female                      524         636
  male                       1211        1420
ae.artery <- to_factor(AEDB$Artery_summary)
table(ae.artery, ae.gender, dnn = c("Sex", "Artery"))
                                                                                         Artery
Sex                                                                                       female male
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA      0    0
  carotid (left & right)                                                                     805 1781
  femoral/iliac (left, right or both sides)                                                  320  796
  other carotid arteries (common, external)                                                   17   35
  carotid bypass and injury (left, right or both sides)                                        6    3
  aneurysmata (carotid & femoral)                                                              1    0
  aorta                                                                                        3    5
  other arteries (renal, popliteal, vertebral)                                                 4    9
  femoral bypass, angioseal and injury (left, right or both sides)                             4    2
rm(ae.gender, ae.hospital, ae.artery)

# I change numeric and factors manually because, well, I wouldn't know how to fix it otherwise
# to have this 'tibble' work with 'tableone'... :-)

AEDB$Age <- as.numeric(AEDB$Age)
AEDB$diastoli <- as.numeric(AEDB$diastoli)
AEDB$systolic <- as.numeric(AEDB$systolic)

AEDB$TC_finalCU <- as.numeric(AEDB$TC_finalCU)
AEDB$LDL_finalCU <- as.numeric(AEDB$LDL_finalCU)
AEDB$HDL_finalCU <- as.numeric(AEDB$HDL_finalCU)
AEDB$TG_finalCU <- as.numeric(AEDB$TG_finalCU)

AEDB$TC_final <- as.numeric(AEDB$TC_final)
AEDB$LDL_final <- as.numeric(AEDB$LDL_final)
AEDB$HDL_final <- as.numeric(AEDB$HDL_final)
AEDB$TG_final <- as.numeric(AEDB$TG_final)

AEDB$Age <- as.numeric(AEDB$Age)
AEDB$GFR_MDRD <- as.numeric(AEDB$GFR_MDRD)
AEDB$BMI <- as.numeric(AEDB$BMI)
AEDB$eCigarettes <- as.numeric(AEDB$eCigarettes)
AEDB$ePackYearsSmoking <- as.numeric(AEDB$ePackYearsSmoking)
AEDB$EP_composite_time <- as.numeric(AEDB$EP_composite_time)
AEDB$EP_major_time <- as.numeric(AEDB$EP_major_time)

require(labelled)
AEDB$ORyear <- to_factor(AEDB$ORyear)
AEDB$Gender <- to_factor(AEDB$Gender)
AEDB$Hospital <- to_factor(AEDB$Hospital)
AEDB$KDOQI <- to_factor(AEDB$KDOQI)
AEDB$BMI_WHO <- to_factor(AEDB$BMI_WHO)
AEDB$DiabetesStatus <- to_factor(AEDB$DiabetesStatus)
AEDB$SmokerStatus <- to_factor(AEDB$SmokerStatus)
AEDB$AlcoholUse <- to_factor(AEDB$AlcoholUse)

AEDB$Hypertension.selfreport <- to_factor(AEDB$Hypertension1)
AEDB$Hypertension.selfreportdrug <- to_factor(AEDB$Hypertension2)
AEDB$Hypertension.composite <- to_factor(AEDB$Hypertension.composite)
AEDB$Hypertension.drugs <- to_factor(AEDB$Hypertension.drugs)

AEDB$Med.anticoagulants <- to_factor(AEDB$Med.anticoagulants)
AEDB$Med.all.antiplatelet <- to_factor(AEDB$Med.all.antiplatelet)
AEDB$Med.Statin.LLD <- to_factor(AEDB$Med.Statin.LLD)

AEDB$Stroke_Dx <- to_factor(AEDB$Stroke_Dx)
AEDB$CAD_history <- to_factor(AEDB$CAD_history)
AEDB$PAOD <- to_factor(AEDB$PAOD)
AEDB$Peripheral.interv <- to_factor(AEDB$Peripheral.interv)

AEDB$sympt <- to_factor(AEDB$sympt)
AEDB$Symptoms.3g <- to_factor(AEDB$Symptoms.3g)
AEDB$Symptoms.4g <- to_factor(AEDB$Symptoms.4g)
AEDB$Symptoms.5G <- to_factor(AEDB$Symptoms.5G)
AEDB$AsymptSympt <- to_factor(AEDB$AsymptSympt)
AEDB$AsymptSympt2G <- to_factor(AEDB$AsymptSympt2G)

AEDB$restenos <- to_factor(AEDB$restenos)
AEDB$stenose <- to_factor(AEDB$stenose)
AEDB$EP_composite <- to_factor(AEDB$EP_composite)
AEDB$EP_major <- to_factor(AEDB$EP_major)
AEDB$Macrophages.bin <- to_factor(AEDB$Macrophages.bin)
AEDB$SMC.bin <- to_factor(AEDB$SMC.bin)
AEDB$IPH.bin <- to_factor(AEDB$IPH.bin)
AEDB$Calc.bin <- to_factor(AEDB$Calc.bin)
AEDB$Collagen.bin <- to_factor(AEDB$Collagen.bin)
AEDB$Fat.bin_10 <- to_factor(AEDB$Fat.bin_10)
AEDB$Fat.bin_40 <- to_factor(AEDB$Fat.bin_40)
AEDB$OverallPlaquePhenotype <- to_factor(AEDB$OverallPlaquePhenotype)
AEDB$Plaque_Vulnerability_Index <- to_factor(AEDB$Plaque_Vulnerability_Index)

AEDB$Artery_summary <- to_factor(AEDB$Artery_summary)

AEDB$informedconsent <- to_factor(AEDB$informedconsent)

AEDB.CEA <- subset(AEDB,
                    (Artery_summary == "carotid (left & right)" | Artery_summary == "other carotid arteries (common, external)") & # we only want carotids
                       informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
                       informedconsent != "no, died" &
                       informedconsent != "yes, no tissue, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no health treatment" &
                       informedconsent != "yes, no tissue, no questionnaires" &
                       informedconsent != "yes, no tissue, health treatment when possible" &
                       informedconsent != "yes, no tissue" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
                       informedconsent != "no, doesn't want to" &
                       informedconsent != "no, unable to sign" &
                       informedconsent != "no, no reaction" &
                       informedconsent != "no, lost" &
                       informedconsent != "no, too old" &
                       informedconsent != "yes, no medical info, health treatment when possible" &
                       informedconsent != "no (never asked for IC because there was no tissue)" &
                       informedconsent != "no, endpoint" &
                       informedconsent != "nooit geincludeerd" & 
                     !is.na(AsymptSympt2G))
# AEDB.CEA[1:10, 1:10]
dim(AEDB.CEA)
[1] 2421 1111
AEDB.full <- subset(AEDB,
                    informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
                       informedconsent != "no, died" &
                       informedconsent != "yes, no tissue, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no health treatment" &
                       informedconsent != "yes, no tissue, no questionnaires" &
                       informedconsent != "yes, no tissue, health treatment when possible" &
                       informedconsent != "yes, no tissue" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
                       informedconsent != "no, doesn't want to" &
                       informedconsent != "no, unable to sign" &
                       informedconsent != "no, no reaction" &
                       informedconsent != "no, lost" &
                       informedconsent != "no, too old" &
                       informedconsent != "yes, no medical info, health treatment when possible" &
                       informedconsent != "no (never asked for IC because there was no tissue)" &
                       informedconsent != "no, endpoint" &
                       informedconsent != "nooit geincludeerd")
# AEDB.CEA[1:10, 1:10]
dim(AEDB.full)
[1] 3458 1111
cat("===========================================================================================\n")
===========================================================================================
cat("CREATE BASELINE TABLE\n")
CREATE BASELINE TABLE
# Baseline table variables
basetable_vars = c("Hospital", "ORyear",
                   "Age", "Gender", 
                   # "TC_finalCU", "LDL_finalCU", "HDL_finalCU", "TG_finalCU", 
                   "TC_final", "LDL_final", "HDL_final", "TG_final", 
                   # "hsCRP_plasma",
                   "systolic", "diastoli", "GFR_MDRD", "BMI", 
                   "KDOQI", "BMI_WHO",
                   "SmokerStatus", "AlcoholUse",
                   "DiabetesStatus", 
                   "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs", 
                   "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
                   "Stroke_Dx", "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G",
                   "restenos", "stenose",
                   "CAD_history", "PAOD", "Peripheral.interv", 
                   "EP_composite", "EP_composite_time", "EP_major", "EP_major_time",
                   "MAC_rankNorm", "SMC_rankNorm", "Macrophages.bin", "SMC.bin",
                   "Neutrophils_rankNorm", "MastCells_rankNorm",
                   "IPH.bin", "VesselDensity_rankNorm",
                   "Calc.bin", "Collagen.bin", 
                   "Fat.bin_10", "Fat.bin_40", "OverallPlaquePhenotype", "Plaque_Vulnerability_Index")

basetable_bin = c("Gender", 
                  "KDOQI", "BMI_WHO",
                  "SmokerStatus", "AlcoholUse",
                  "DiabetesStatus", 
                  "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs", 
                  "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
                  "Stroke_Dx", "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G",
                  "restenos", "stenose",
                  "CAD_history", "PAOD", "Peripheral.interv", 
                  "EP_composite", "Macrophages.bin", "SMC.bin",
                  "IPH.bin", 
                  "Calc.bin", "Collagen.bin", 
                  "Fat.bin_10", "Fat.bin_40", "OverallPlaquePhenotype", "Plaque_Vulnerability_Index")
# basetable_bin

basetable_con = basetable_vars[!basetable_vars %in% basetable_bin]
# basetable_con

Athero-Express Biobank Study: baseline characteristics

Showing the baseline table of the whole Athero-Express Biobank.

# Create baseline tables
# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
AEDB.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                         # factorVars = basetable_bin,
                                         # strata = "Symptoms.4g",
                                         data = AEDB.full, includeNA = TRUE), 
                          nonnormal = c(), missing = TRUE,
                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
                          format = "pf", 
                          contDigits = 3)[,1:3]
                                      
                                       level                                                                     Overall          Missing
  n                                                                                                                 3458                 
  Hospital % (freq)                    St. Antonius, Nieuwegein                                                     45.3 (1567)    0.0   
                                       UMC Utrecht                                                                  54.7 (1891)          
  ORyear % (freq)                      No data available/missing                                                     0.0 (   0)    0.0   
                                       2002                                                                          2.5 (  86)          
                                       2003                                                                          5.5 ( 191)          
                                       2004                                                                          7.7 ( 265)          
                                       2005                                                                          8.0 ( 276)          
                                       2006                                                                          7.3 ( 254)          
                                       2007                                                                          6.0 ( 206)          
                                       2008                                                                          5.5 ( 190)          
                                       2009                                                                          7.1 ( 246)          
                                       2010                                                                          8.0 ( 278)          
                                       2011                                                                          7.0 ( 243)          
                                       2012                                                                          8.2 ( 284)          
                                       2013                                                                          6.8 ( 235)          
                                       2014                                                                          8.1 ( 281)          
                                       2015                                                                          2.2 (  77)          
                                       2016                                                                          3.5 ( 121)          
                                       2017                                                                          2.3 (  79)          
                                       2018                                                                          2.2 (  77)          
                                       2019                                                                          2.0 (  69)          
  Age (mean (SD))                                                                                                 68.733 (9.214)   0.0   
  Gender % (freq)                      female                                                                       29.7 (1026)    0.0   
                                       male                                                                         70.3 (2432)          
  TC_final (mean (SD))                                                                                             4.769 (1.406)  45.9   
  LDL_final (mean (SD))                                                                                            2.762 (1.061)  53.6   
  HDL_final (mean (SD))                                                                                            1.207 (0.436)  50.2   
  TG_final (mean (SD))                                                                                             1.738 (1.099)  51.0   
  systolic (mean (SD))                                                                                           150.820 (24.992) 13.0   
  diastoli (mean (SD))                                                                                            80.072 (22.444) 13.0   
  GFR_MDRD (mean (SD))                                                                                            74.865 (24.412)  6.6   
  BMI (mean (SD))                                                                                                 26.395 (3.997)   5.8   
  KDOQI % (freq)                       No data available/missing                                                     0.0 (   0)    6.6   
                                       Normal kidney function                                                       21.7 ( 750)          
                                       CKD 2 (Mild)                                                                 47.9 (1656)          
                                       CKD 3 (Moderate)                                                             21.7 ( 750)          
                                       CKD 4 (Severe)                                                                1.5 (  51)          
                                       CKD 5 (Failure)                                                               0.6 (  22)          
                                       <NA>                                                                          6.6 ( 229)          
  BMI_WHO % (freq)                     No data available/missing                                                     0.0 (   0)    5.8   
                                       Underweight                                                                   1.1 (  37)          
                                       Normal                                                                       35.3 (1222)          
                                       Overweight                                                                   43.6 (1508)          
                                       Obese                                                                        14.1 ( 489)          
                                       <NA>                                                                          5.8 ( 202)          
  SmokerStatus % (freq)                Current smoker                                                               34.3 (1187)    5.7   
                                       Ex-smoker                                                                    49.6 (1716)          
                                       Never smoked                                                                 10.4 ( 358)          
                                       <NA>                                                                          5.7 ( 197)          
  AlcoholUse % (freq)                  No                                                                           32.2 (1114)    4.1   
                                       Yes                                                                          63.7 (2203)          
                                       <NA>                                                                          4.1 ( 141)          
  DiabetesStatus % (freq)              Control (no Diabetes Dx/Med)                                                 73.3 (2534)    1.2   
                                       Diabetes                                                                     25.5 ( 883)          
                                       <NA>                                                                          1.2 (  41)          
  Hypertension.selfreport % (freq)     No data available/missing                                                     0.0 (   0)    3.6   
                                       no                                                                           23.7 ( 820)          
                                       yes                                                                          72.7 (2513)          
                                       <NA>                                                                          3.6 ( 125)          
  Hypertension.selfreportdrug % (freq) No data available/missing                                                     0.0 (   0)    5.0   
                                       no                                                                           29.0 (1002)          
                                       yes                                                                          66.0 (2284)          
                                       <NA>                                                                          5.0 ( 172)          
  Hypertension.composite % (freq)      No data available/missing                                                     0.0 (   0)    1.3   
                                       no                                                                           13.5 ( 466)          
                                       yes                                                                          85.2 (2947)          
                                       <NA>                                                                          1.3 (  45)          
  Hypertension.drugs % (freq)          No data available/missing                                                     0.0 (   0)    1.5   
                                       no                                                                           21.0 ( 725)          
                                       yes                                                                          77.5 (2681)          
                                       <NA>                                                                          1.5 (  52)          
  Med.anticoagulants % (freq)          No data available/missing                                                     0.0 (   0)    1.6   
                                       no                                                                           85.8 (2967)          
                                       yes                                                                          12.6 ( 434)          
                                       <NA>                                                                          1.6 (  57)          
  Med.all.antiplatelet % (freq)        No data available/missing                                                     0.0 (   0)    1.6   
                                       no                                                                           13.3 ( 459)          
                                       yes                                                                          85.1 (2943)          
                                       <NA>                                                                          1.6 (  56)          
  Med.Statin.LLD % (freq)              No data available/missing                                                     0.0 (   0)    1.5   
                                       no                                                                           21.0 ( 727)          
                                       yes                                                                          77.4 (2678)          
                                       <NA>                                                                          1.5 (  53)          
  Stroke_Dx % (freq)                   Missing                                                                       0.0 (   0)    7.5   
                                       No stroke diagnosed                                                          75.6 (2613)          
                                       Stroke diagnosed                                                             16.9 ( 586)          
                                       <NA>                                                                          7.5 ( 259)          
  sympt % (freq)                       missing                                                                       0.0 (   0)   28.3   
                                       Asymptomatic                                                                  9.1 ( 314)          
                                       TIA                                                                          28.0 ( 968)          
                                       minor stroke                                                                 11.8 ( 408)          
                                       Major stroke                                                                  6.9 ( 238)          
                                       Amaurosis fugax                                                              11.0 ( 380)          
                                       Four vessel disease                                                           1.1 (  39)          
                                       Vertebrobasilary TIA                                                          0.1 (   5)          
                                       Retinal infarction                                                            1.0 (  34)          
                                       Symptomatic, but aspecific symtoms                                            1.6 (  57)          
                                       Contralateral symptomatic occlusion                                           0.3 (  11)          
                                       retinal infarction                                                            0.2 (   6)          
                                       armclaudication due to occlusion subclavian artery, CEA needed for bypass     0.0 (   1)          
                                       retinal infarction + TIAs                                                     0.0 (   0)          
                                       Ocular ischemic syndrome                                                      0.5 (  16)          
                                       ischemisch glaucoom                                                           0.0 (   0)          
                                       subclavian steal syndrome                                                     0.1 (   2)          
                                       TGA                                                                           0.0 (   0)          
                                       <NA>                                                                         28.3 ( 979)          
  Symptoms.5G % (freq)                 Asymptomatic                                                                  9.1 ( 314)   28.3   
                                       Ocular                                                                       11.5 ( 396)          
                                       Other                                                                         3.2 ( 110)          
                                       Retinal infarction                                                            1.2 (  40)          
                                       Stroke                                                                       18.7 ( 646)          
                                       TIA                                                                          28.1 ( 973)          
                                       <NA>                                                                         28.3 ( 979)          
  AsymptSympt % (freq)                 Asymptomatic                                                                  9.1 ( 314)   28.3   
                                       Ocular and others                                                            15.8 ( 546)          
                                       Symptomatic                                                                  46.8 (1619)          
                                       <NA>                                                                         28.3 ( 979)          
  AsymptSympt2G % (freq)               Asymptomatic                                                                  9.1 ( 314)   28.3   
                                       Symptomatic                                                                  62.6 (2165)          
                                       <NA>                                                                         28.3 ( 979)          
  restenos % (freq)                    missing                                                                       0.0 (   0)    3.9   
                                       de novo                                                                      87.0 (3007)          
                                       restenosis                                                                    9.0 ( 312)          
                                       stenose bij angioseal na PTCA                                                 0.1 (   5)          
                                       <NA>                                                                          3.9 ( 134)          
  stenose % (freq)                     missing                                                                       0.0 (   0)    6.7   
                                       0-49%                                                                         0.7 (  23)          
                                       50-70%                                                                        6.9 ( 240)          
                                       70-90%                                                                       36.0 (1246)          
                                       90-99%                                                                       30.0 (1038)          
                                       100% (Occlusion)                                                             14.4 ( 497)          
                                       NA                                                                            0.1 (   3)          
                                       50-99%                                                                        2.5 (  86)          
                                       70-99%                                                                        2.7 (  93)          
                                       99                                                                            0.1 (   2)          
                                       <NA>                                                                          6.7 ( 230)          
  CAD_history % (freq)                 Missing                                                                       0.0 (   0)    2.0   
                                       No history CAD                                                               64.1 (2216)          
                                       History CAD                                                                  33.9 (1173)          
                                       <NA>                                                                          2.0 (  69)          
  PAOD % (freq)                        missing/no data                                                               0.0 (   0)    1.5   
                                       no                                                                           55.7 (1927)          
                                       yes                                                                          42.8 (1479)          
                                       <NA>                                                                          1.5 (  52)          
  Peripheral.interv % (freq)           no                                                                           68.0 (2352)    2.9   
                                       yes                                                                          29.1 (1006)          
                                       <NA>                                                                          2.9 ( 100)          
  EP_composite % (freq)                No data available.                                                            0.0 (   0)    5.1   
                                       No composite endpoints                                                       63.1 (2181)          
                                       Composite endpoints                                                          31.9 (1102)          
                                       <NA>                                                                          5.1 ( 175)          
  EP_composite_time (mean (SD))                                                                                    2.335 (1.166)   5.2   
  EP_major % (freq)                    No data available.                                                            0.0 (   0)    5.1   
                                       No major events (endpoints)                                                  83.3 (2882)          
                                       Major events (endpoints)                                                     11.6 ( 401)          
                                       <NA>                                                                          5.1 ( 175)          
  EP_major_time (mean (SD))                                                                                        2.735 (0.988)   5.2   
  MAC_rankNorm (mean (SD))                                                                                         0.004 (0.993)  32.9   
  SMC_rankNorm (mean (SD))                                                                                        -0.003 (1.004)  32.9   
  Macrophages.bin % (freq)             no/minor                                                                     41.6 (1437)   26.3   
                                       moderate/heavy                                                               32.2 (1112)          
                                       <NA>                                                                         26.3 ( 909)          
  SMC.bin % (freq)                     no/minor                                                                     23.1 ( 799)   25.9   
                                       moderate/heavy                                                               51.0 (1763)          
                                       <NA>                                                                         25.9 ( 896)          
  Neutrophils_rankNorm (mean (SD))                                                                                 0.010 (0.953)  91.0   
  MastCells_rankNorm (mean (SD))                                                                                  -0.009 (1.000)  93.0   
  IPH.bin % (freq)                     no                                                                           31.8 (1099)   25.3   
                                       yes                                                                          42.9 (1483)          
                                       <NA>                                                                         25.3 ( 876)          
  VesselDensity_rankNorm (mean (SD))                                                                               0.017 (0.978)  48.3   
  Calc.bin % (freq)                    no/minor                                                                     38.0 (1314)   25.3   
                                       moderate/heavy                                                               36.7 (1269)          
                                       <NA>                                                                         25.3 ( 875)          
  Collagen.bin % (freq)                no/minor                                                                     14.3 ( 496)   25.8   
                                       moderate/heavy                                                               59.9 (2071)          
                                       <NA>                                                                         25.8 ( 891)          
  Fat.bin_10 % (freq)                   <10%                                                                        31.7 (1096)   25.3   
                                        >10%                                                                        43.0 (1488)          
                                       <NA>                                                                         25.3 ( 874)          
  Fat.bin_40 % (freq)                  <40%                                                                         59.5 (2056)   25.3   
                                       >40%                                                                         15.3 ( 528)          
                                       <NA>                                                                         25.3 ( 874)          
  OverallPlaquePhenotype % (freq)      atheromatous                                                                 14.7 ( 507)   25.9   
                                       fibroatheromatous                                                            22.2 ( 769)          
                                       fibrous                                                                      37.2 (1285)          
                                       <NA>                                                                         25.9 ( 897)          
  Plaque_Vulnerability_Index % (freq)  0                                                                            35.0 (1212)    0.0   
                                       1                                                                            17.1 ( 590)          
                                       2                                                                            19.0 ( 657)          
                                       3                                                                            18.0 ( 622)          
                                       4                                                                             8.0 ( 277)          
                                       5                                                                             2.9 ( 100)          
# Create baseline tables
# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
AEDB.CEA.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                         # factorVars = basetable_bin,
                                         # strata = "Symptoms.4g",
                                         data = AEDB.CEA, includeNA = TRUE), 
                          nonnormal = c(), missing = TRUE,
                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
                          format = "pf", 
                          contDigits = 3)[,1:3]
                                      
                                       level                                                                     Overall          Missing
  n                                                                                                                 2421                 
  Hospital % (freq)                    St. Antonius, Nieuwegein                                                     39.2 ( 948)    0.0   
                                       UMC Utrecht                                                                  60.8 (1473)          
  ORyear % (freq)                      No data available/missing                                                     0.0 (   0)    0.0   
                                       2002                                                                          3.3 (  81)          
                                       2003                                                                          6.5 ( 157)          
                                       2004                                                                          7.8 ( 190)          
                                       2005                                                                          7.6 ( 185)          
                                       2006                                                                          7.6 ( 183)          
                                       2007                                                                          6.3 ( 152)          
                                       2008                                                                          5.7 ( 138)          
                                       2009                                                                          7.5 ( 181)          
                                       2010                                                                          6.6 ( 159)          
                                       2011                                                                          6.7 ( 163)          
                                       2012                                                                          7.3 ( 176)          
                                       2013                                                                          6.2 ( 149)          
                                       2014                                                                          6.7 ( 163)          
                                       2015                                                                          3.1 (  76)          
                                       2016                                                                          3.5 (  85)          
                                       2017                                                                          2.7 (  65)          
                                       2018                                                                          2.7 (  66)          
                                       2019                                                                          2.1 (  52)          
  Age (mean (SD))                                                                                                 69.105 (9.302)   0.0   
  Gender % (freq)                      female                                                                       30.5 ( 738)    0.0   
                                       male                                                                         69.5 (1683)          
  TC_final (mean (SD))                                                                                             4.786 (1.457)  38.0   
  LDL_final (mean (SD))                                                                                            2.808 (1.081)  45.6   
  HDL_final (mean (SD))                                                                                            1.203 (0.440)  41.7   
  TG_final (mean (SD))                                                                                             1.709 (1.031)  42.8   
  systolic (mean (SD))                                                                                           152.419 (25.166) 11.3   
  diastoli (mean (SD))                                                                                            81.318 (25.188) 11.3   
  GFR_MDRD (mean (SD))                                                                                            73.121 (21.152)  5.4   
  BMI (mean (SD))                                                                                                 26.488 (3.977)   5.9   
  KDOQI % (freq)                       No data available/missing                                                     0.0 (   0)    5.5   
                                       Normal kidney function                                                       19.1 ( 462)          
                                       CKD 2 (Mild)                                                                 50.9 (1232)          
                                       CKD 3 (Moderate)                                                             22.8 ( 553)          
                                       CKD 4 (Severe)                                                                1.3 (  32)          
                                       CKD 5 (Failure)                                                               0.4 (  10)          
                                       <NA>                                                                          5.5 ( 132)          
  BMI_WHO % (freq)                     No data available/missing                                                     0.0 (   0)    5.9   
                                       Underweight                                                                   1.0 (  24)          
                                       Normal                                                                       35.1 ( 850)          
                                       Overweight                                                                   43.4 (1051)          
                                       Obese                                                                        14.5 ( 352)          
                                       <NA>                                                                          5.9 ( 144)          
  SmokerStatus % (freq)                Current smoker                                                               33.2 ( 803)    5.9   
                                       Ex-smoker                                                                    48.0 (1163)          
                                       Never smoked                                                                 12.9 ( 313)          
                                       <NA>                                                                          5.9 ( 142)          
  AlcoholUse % (freq)                  No                                                                           34.5 ( 835)    4.0   
                                       Yes                                                                          61.5 (1488)          
                                       <NA>                                                                          4.0 (  98)          
  DiabetesStatus % (freq)              Control (no Diabetes Dx/Med)                                                 75.2 (1820)    1.1   
                                       Diabetes                                                                     23.7 ( 574)          
                                       <NA>                                                                          1.1 (  27)          
  Hypertension.selfreport % (freq)     No data available/missing                                                     0.0 (   0)    3.2   
                                       no                                                                           24.3 ( 589)          
                                       yes                                                                          72.4 (1754)          
                                       <NA>                                                                          3.2 (  78)          
  Hypertension.selfreportdrug % (freq) No data available/missing                                                     0.0 (   0)    4.4   
                                       no                                                                           29.9 ( 725)          
                                       yes                                                                          65.6 (1589)          
                                       <NA>                                                                          4.4 ( 107)          
  Hypertension.composite % (freq)      No data available/missing                                                     0.0 (   0)    1.2   
                                       no                                                                           14.6 ( 353)          
                                       yes                                                                          84.3 (2040)          
                                       <NA>                                                                          1.2 (  28)          
  Hypertension.drugs % (freq)          No data available/missing                                                     0.0 (   0)    1.4   
                                       no                                                                           23.3 ( 565)          
                                       yes                                                                          75.3 (1823)          
                                       <NA>                                                                          1.4 (  33)          
  Med.anticoagulants % (freq)          No data available/missing                                                     0.0 (   0)    1.6   
                                       no                                                                           87.3 (2114)          
                                       yes                                                                          11.1 ( 269)          
                                       <NA>                                                                          1.6 (  38)          
  Med.all.antiplatelet % (freq)        No data available/missing                                                     0.0 (   0)    1.5   
                                       no                                                                           12.2 ( 295)          
                                       yes                                                                          86.3 (2090)          
                                       <NA>                                                                          1.5 (  36)          
  Med.Statin.LLD % (freq)              No data available/missing                                                     0.0 (   0)    1.4   
                                       no                                                                           20.3 ( 491)          
                                       yes                                                                          78.3 (1896)          
                                       <NA>                                                                          1.4 (  34)          
  Stroke_Dx % (freq)                   Missing                                                                       0.0 (   0)    6.9   
                                       No stroke diagnosed                                                          71.5 (1731)          
                                       Stroke diagnosed                                                             21.6 ( 524)          
                                       <NA>                                                                          6.9 ( 166)          
  sympt % (freq)                       missing                                                                       0.0 (   0)    0.0   
                                       Asymptomatic                                                                 11.2 ( 270)          
                                       TIA                                                                          39.7 ( 961)          
                                       minor stroke                                                                 16.8 ( 407)          
                                       Major stroke                                                                  9.8 ( 238)          
                                       Amaurosis fugax                                                              15.7 ( 379)          
                                       Four vessel disease                                                           1.6 (  38)          
                                       Vertebrobasilary TIA                                                          0.2 (   5)          
                                       Retinal infarction                                                            1.4 (  34)          
                                       Symptomatic, but aspecific symtoms                                            2.2 (  53)          
                                       Contralateral symptomatic occlusion                                           0.5 (  11)          
                                       retinal infarction                                                            0.2 (   6)          
                                       armclaudication due to occlusion subclavian artery, CEA needed for bypass     0.0 (   1)          
                                       retinal infarction + TIAs                                                     0.0 (   0)          
                                       Ocular ischemic syndrome                                                      0.7 (  16)          
                                       ischemisch glaucoom                                                           0.0 (   0)          
                                       subclavian steal syndrome                                                     0.1 (   2)          
                                       TGA                                                                           0.0 (   0)          
  Symptoms.5G % (freq)                 Asymptomatic                                                                 11.2 ( 270)    0.0   
                                       Ocular                                                                       16.3 ( 395)          
                                       Other                                                                         4.3 ( 105)          
                                       Retinal infarction                                                            1.7 (  40)          
                                       Stroke                                                                       26.6 ( 645)          
                                       TIA                                                                          39.9 ( 966)          
  AsymptSympt % (freq)                 Asymptomatic                                                                 11.2 ( 270)    0.0   
                                       Ocular and others                                                            22.3 ( 540)          
                                       Symptomatic                                                                  66.5 (1611)          
  AsymptSympt2G % (freq)               Asymptomatic                                                                 11.2 ( 270)    0.0   
                                       Symptomatic                                                                  88.8 (2151)          
  restenos % (freq)                    missing                                                                       0.0 (   0)    1.4   
                                       de novo                                                                      93.7 (2268)          
                                       restenosis                                                                    4.9 ( 118)          
                                       stenose bij angioseal na PTCA                                                 0.0 (   0)          
                                       <NA>                                                                          1.4 (  35)          
  stenose % (freq)                     missing                                                                       0.0 (   0)    2.0   
                                       0-49%                                                                         0.5 (  13)          
                                       50-70%                                                                        7.8 ( 189)          
                                       70-90%                                                                       46.6 (1127)          
                                       90-99%                                                                       38.3 ( 927)          
                                       100% (Occlusion)                                                              1.3 (  31)          
                                       NA                                                                            0.0 (   1)          
                                       50-99%                                                                        0.6 (  15)          
                                       70-99%                                                                        2.8 (  68)          
                                       99                                                                            0.1 (   2)          
                                       <NA>                                                                          2.0 (  48)          
  CAD_history % (freq)                 Missing                                                                       0.0 (   0)    1.9   
                                       No history CAD                                                               66.8 (1618)          
                                       History CAD                                                                  31.2 ( 756)          
                                       <NA>                                                                          1.9 (  47)          
  PAOD % (freq)                        missing/no data                                                               0.0 (   0)    2.0   
                                       no                                                                           77.5 (1876)          
                                       yes                                                                          20.5 ( 497)          
                                       <NA>                                                                          2.0 (  48)          
  Peripheral.interv % (freq)           no                                                                           77.2 (1868)    2.9   
                                       yes                                                                          19.9 ( 482)          
                                       <NA>                                                                          2.9 (  71)          
  EP_composite % (freq)                No data available.                                                            0.0 (   0)    5.0   
                                       No composite endpoints                                                       70.6 (1709)          
                                       Composite endpoints                                                          24.4 ( 590)          
                                       <NA>                                                                          5.0 ( 122)          
  EP_composite_time (mean (SD))                                                                                    2.479 (1.109)   5.2   
  EP_major % (freq)                    No data available.                                                            0.0 (   0)    5.0   
                                       No major events (endpoints)                                                  83.3 (2016)          
                                       Major events (endpoints)                                                     11.7 ( 283)          
                                       <NA>                                                                          5.0 ( 122)          
  EP_major_time (mean (SD))                                                                                        2.707 (0.977)   5.2   
  MAC_rankNorm (mean (SD))                                                                                         0.177 (0.952)  29.7   
  SMC_rankNorm (mean (SD))                                                                                        -0.060 (0.962)  29.9   
  Macrophages.bin % (freq)             no/minor                                                                     34.9 ( 846)   24.1   
                                       moderate/heavy                                                               40.9 ( 991)          
                                       <NA>                                                                         24.1 ( 584)          
  SMC.bin % (freq)                     no/minor                                                                     24.9 ( 602)   23.8   
                                       moderate/heavy                                                               51.3 (1242)          
                                       <NA>                                                                         23.8 ( 577)          
  Neutrophils_rankNorm (mean (SD))                                                                                 0.030 (0.951)  87.4   
  MastCells_rankNorm (mean (SD))                                                                                  -0.010 (1.002)  90.0   
  IPH.bin % (freq)                     no                                                                           30.7 ( 744)   23.5   
                                       yes                                                                          45.8 (1108)          
                                       <NA>                                                                         23.5 ( 569)          
  VesselDensity_rankNorm (mean (SD))                                                                               0.056 (0.981)  35.1   
  Calc.bin % (freq)                    no/minor                                                                     41.6 (1006)   23.4   
                                       moderate/heavy                                                               35.1 ( 849)          
                                       <NA>                                                                         23.4 ( 566)          
  Collagen.bin % (freq)                no/minor                                                                     15.8 ( 382)   23.6   
                                       moderate/heavy                                                               60.6 (1467)          
                                       <NA>                                                                         23.6 ( 572)          
  Fat.bin_10 % (freq)                   <10%                                                                        22.4 ( 542)   23.3   
                                        >10%                                                                        54.3 (1314)          
                                       <NA>                                                                         23.3 ( 565)          
  Fat.bin_40 % (freq)                  <40%                                                                         56.2 (1360)   23.3   
                                       >40%                                                                         20.5 ( 496)          
                                       <NA>                                                                         23.3 ( 565)          
  OverallPlaquePhenotype % (freq)      atheromatous                                                                 19.8 ( 480)   23.7   
                                       fibroatheromatous                                                            27.8 ( 672)          
                                       fibrous                                                                      28.7 ( 695)          
                                       <NA>                                                                         23.7 ( 574)          
  Plaque_Vulnerability_Index % (freq)  0                                                                            29.5 ( 713)    0.0   
                                       1                                                                            14.3 ( 347)          
                                       2                                                                            19.7 ( 478)          
                                       3                                                                            22.1 ( 535)          
                                       4                                                                            10.4 ( 251)          
                                       5                                                                             4.0 (  97)          

Athero-Express Genomics Study: prepare

Let’s combine the full Athero-Express Biobank Study with the key-table containing the AEGS data.

NOTE: this should sum to 2,124 samples with genotypes.

AEGS <- merge(AEDB.full, AEGS123.sampleList.keytable, by.x = "STUDY_NUMBER", by.y = "STUDY_NUMBER", sort = FALSE,
                  all = TRUE)

dim(AEGS)
[1] 3571 1135
AEGS$UPID.y <- NULL
names(AEGS)[names(AEGS) == "UPID.x"] <- "UPID"
AEGS$Age.y <- NULL
names(AEGS)[names(AEGS) == "Age.x"] <- "Age"

table(AEGS$CHIP, useNA = "ifany")

AffyAxiomCEU     AffySNP5       IllGSA         <NA> 
         918          687          519         1447 
AEGS$GWAS <- AEGS$CHIP
AEGS$GWAS[is.na(AEGS$GWAS)] <- "not genotyped"
AEGS$GWAS[AEGS$GWAS != "not genotyped"] <- "genotyped"

table(AEGS$CHIP, AEGS$GWAS, useNA = "ifany")
              
               genotyped not genotyped
  AffyAxiomCEU       918             0
  AffySNP5           687             0
  IllGSA             519             0
  <NA>                 0          1447

Also a visualisation of the AEGS with AEDB overlaps.

library(UpSetR)
require(ggplot2)
require(plyr)
Loading required package: plyr
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Attaching package: 'plyr'

The following object is masked from 'package:ggpubr':

    mutate

The following object is masked from 'package:purrr':

    compact

The following objects are masked from 'package:dplyr':

    arrange, count, desc, failwith, id, mutate, rename, summarise, summarize
require(gridExtra)
Loading required package: gridExtra

Attaching package: 'gridExtra'

The following object is masked from 'package:dplyr':

    combine
require(grid)

AEDB.availGWAS = list(
AEGS1 = subset(AEGS, CHIP == "AffySNP5", select = c("STUDY_NUMBER"))[,1],
AEGS2 = subset(AEGS, CHIP == "AffyAxiomCEU", select = c("STUDY_NUMBER"))[,1],
AEGS3 = subset(AEGS, CHIP == "IllGSA", select = c("STUDY_NUMBER"))[,1],
AEDB = AEGS$STUDY_NUMBER)

p1 <- UpSetR::upset(fromList(AEDB.availGWAS), 
                    sets = c("AEDB", "AEGS1", "AEGS2", "AEGS3"), 
                    main.bar.color = c(uithof_color[15], uithof_color[2], uithof_color[3], uithof_color[21]), 
                    mainbar.y.label = "intersection sample size", 
                    sets.bar.color = c(uithof_color[15], uithof_color[2], uithof_color[3], uithof_color[21]), 
                    sets.x.label = "sample size", keep.order = TRUE)
pdf(paste0(PLOT_loc, "/", Today, ".overlap.AEDB_AEGS123.UpSetR.pdf"))
  p1
dev.off()
quartz_off_screen 
                2 
png(paste0(PLOT_loc, "/", Today, ".overlap.AEDB_AEGS123.UpSetR.png"))
  p1
dev.off()
quartz_off_screen 
                2 

p1

rm(p1)
table(AEGS$Artery_summary, AEGS$QC2018_FILTER)
                                                                                         
                                                                                          family_discard family_keep issue passed
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA              0           0     0      0
  carotid (left & right)                                                                              20          21    40   1819
  femoral/iliac (left, right or both sides)                                                            1           0     0     99
  other carotid arteries (common, external)                                                            0           0     0      9
  carotid bypass and injury (left, right or both sides)                                                0           0     0      1
  aneurysmata (carotid & femoral)                                                                      0           0     0      0
  aorta                                                                                                0           0     0      0
  other arteries (renal, popliteal, vertebral)                                                         0           0     0      1
  femoral bypass, angioseal and injury (left, right or both sides)                                     0           0     0      0
table(AEGS$informedconsent, AEGS$QC2018_FILTER)
                                                                                                 
                                                                                                  family_discard family_keep issue passed
  missing                                                                                                      0           0     0      0
  no, died                                                                                                     0           0     0      0
  yes                                                                                                         17          16    24   1411
  yes, health treatment when possible                                                                          2           2    10    312
  yes, no health treatment                                                                                     2           2     2     91
  yes, no health treatment, no commercial business                                                             0           0     0     15
  yes, no tissue, no commerical business                                                                       0           0     0      0
  yes, no tissue, no questionnaires, no medical info, no commercial business                                   0           0     0      0
  yes, no questionnaires, no health treatment, no commercial business                                          0           0     0      1
  yes, no questionnaires, health treatment when possible                                                       0           0     0      2
  yes, no tissue, no questionnaires, no health treatment, no commerical business                               0           0     0      0
  yes, no health treatment, no medical info, no commercial business                                            0           0     3     10
  yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business              0           0     0      0
  yes, no questionnaires, no health treatment                                                                  0           0     0      0
  yes, no tissue, no health treatment                                                                          0           0     0      0
  yes, no tissue, no questionnaires                                                                            0           0     0      0
  yes, no tissue, health treatment when possible                                                               0           0     0      0
  yes, no tissue                                                                                               0           0     0      0
  yes, no commerical business                                                                                  0           1     0     35
  yes, health treatment when possible, no commercial business                                                  0           0     0     25
  yes, no medical info, no commercial business                                                                 0           0     0      4
  yes, no questionnaires                                                                                       0           0     0      1
  yes, no tissue, no questionnaires, no health treatment, no medical info                                      0           0     0      0
  yes, no tissue, no questionnaires, no health treatment, no commercial business                               0           0     0      0
  yes, no medical info                                                                                         0           0     1      5
  yes, no questionnaires, no commercial business                                                               0           0     0      0
  yes, no questionnaires, no health treatment, no medical info                                                 0           0     0      1
  yes, no questionnaires, health treatment when possible, no commercial business                               0           0     0      0
  yes,  no health treatment, no medical info                                                                   0           0     0      5
  no, doesn't want to                                                                                          0           0     0      0
  no, unable to sign                                                                                           0           0     0      0
  no, no reaction                                                                                              0           0     0      0
  no, lost                                                                                                     0           0     0      0
  no, too old                                                                                                  0           0     0      0
  yes, no medical info, health treatment when possible                                                         0           0     0      0
  no (never asked for IC because there was no tissue)                                                          0           0     0      0
  yes, no medical info, no commercial business, health treatment when possible                                 0           0     0      2
  no, endpoint                                                                                                 0           0     0      0
  wil niets invullen, wel alles gebruiken                                                                      0           0     0      7
  second informed concents: yes, no commercial business                                                        0           0     0      2
  nooit geincludeerd                                                                                           0           0     0      0
AEGSselect <- subset(AEGS, 
                     informedconsent != "missing" &
                       informedconsent != "no, died" &
                       informedconsent != "yes, no tissue, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no health treatment" &
                       informedconsent != "yes, no tissue, no questionnaires" &
                       informedconsent != "yes, no tissue, health treatment when possible" &
                       informedconsent != "yes, no tissue" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
                       informedconsent != "no, doesn't want to" &
                       informedconsent != "no, unable to sign" &
                       informedconsent != "no, no reaction" &
                       informedconsent != "no, lost" &
                       informedconsent != "no, too old" &
                       informedconsent != "yes, no medical info, health treatment when possible" &
                       informedconsent != "no (never asked for IC because there was no tissue)" &
                       informedconsent != "no, endpoint" &
                       informedconsent != "nooit geincludeerd")

AEGSselect.CEA <- subset(AEGS, !is.na(QC2018_FILTER) & QC2018_FILTER != "issue" & QC2018_FILTER != "family_discard" &
                     (Artery_summary == "carotid (left & right)" | Artery_summary == "other carotid arteries (common, external)") & # we only want carotids
                     informedconsent != "missing" &
                       informedconsent != "no, died" &
                       informedconsent != "yes, no tissue, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
                       informedconsent != "yes, no tissue, no health treatment" &
                       informedconsent != "yes, no tissue, no questionnaires" &
                       informedconsent != "yes, no tissue, health treatment when possible" &
                       informedconsent != "yes, no tissue" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
                       informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
                       informedconsent != "no, doesn't want to" &
                       informedconsent != "no, unable to sign" &
                       informedconsent != "no, no reaction" &
                       informedconsent != "no, lost" &
                       informedconsent != "no, too old" &
                       informedconsent != "yes, no medical info, health treatment when possible" &
                       informedconsent != "no (never asked for IC because there was no tissue)" &
                       informedconsent != "no, endpoint" &
                       informedconsent != "nooit geincludeerd")

dim(AEGSselect)
[1] 3458 1134
table(AEGSselect$Artery_summary, AEGSselect$QC2018_FILTER)
                                                                                         
                                                                                          family_discard family_keep issue passed
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA              0           0     0      0
  carotid (left & right)                                                                              20          21    40   1819
  femoral/iliac (left, right or both sides)                                                            1           0     0     99
  other carotid arteries (common, external)                                                            0           0     0      9
  carotid bypass and injury (left, right or both sides)                                                0           0     0      1
  aneurysmata (carotid & femoral)                                                                      0           0     0      0
  aorta                                                                                                0           0     0      0
  other arteries (renal, popliteal, vertebral)                                                         0           0     0      1
  femoral bypass, angioseal and injury (left, right or both sides)                                     0           0     0      0
table(AEGSselect$Artery_summary, AEGSselect$CHIP)
                                                                                         
                                                                                          AffyAxiomCEU AffySNP5 IllGSA
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA            0        0      0
  carotid (left & right)                                                                           863      550    487
  femoral/iliac (left, right or both sides)                                                          0       72     28
  other carotid arteries (common, external)                                                          2        5      2
  carotid bypass and injury (left, right or both sides)                                              0        1      0
  aneurysmata (carotid & femoral)                                                                    0        0      0
  aorta                                                                                              0        0      0
  other arteries (renal, popliteal, vertebral)                                                       0        1      0
  femoral bypass, angioseal and injury (left, right or both sides)                                   0        0      0
table(AEGSselect$QC2018_FILTER, AEGSselect$CHIP)
                
                 AffyAxiomCEU AffySNP5 IllGSA
  family_discard           12        6      3
  family_keep               8        1     12
  issue                    37        1      2
  passed                  808      621    500
table(AEGSselect$QC2018_FILTER, AEGSselect$SAMPLE_TYPE)
                
                 EDTA blood plaque unknown
  family_discard         15      6       0
  family_keep            13      8       0
  issue                  26     14       0
  passed               1199    729       1
AEDB.temp <- subset(AEGSselect,  select = c("STUDY_NUMBER", "UPID", "Age", "Gender", "Hospital", "Artery_summary", "QC2018_FILTER", "CHIP", "SAMPLE_TYPE"))
require(labelled)
AEDB.temp$Gender <- to_factor(AEDB.temp$Gender)
AEDB.temp$Hospital <- to_factor(AEDB.temp$Hospital)
AEDB.temp$Artery_summary <- to_factor(AEDB.temp$Artery_summary)
AEDB.temp$QC2018_FILTER <- to_factor(AEDB.temp$QC2018_FILTER)
AEDB.temp$CHIP <- to_factor(AEDB.temp$CHIP)
AEDB.temp$SAMPLE_TYPE <- to_factor(AEDB.temp$SAMPLE_TYPE)

DT::datatable(AEDB.temp[1:10,], caption = "Excerpt of the whole AEDB.", rownames = FALSE)

rm(AEDB.temp)

Athero-Express Genomics Study: baseline characteristics

Showing the baseline table of the Athero-Express Genomics Study.

# Create baseline tables
# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
AEGSselect$GWAS <- to_factor(AEGSselect$GWAS)
AEGSselect$CHIP <- to_factor(AEGSselect$CHIP)
AEGSselect$PCA <- to_factor(AEGSselect$PCA)
AEGSselect$SAMPLE_TYPE <- to_factor(AEGSselect$SAMPLE_TYPE)
AEGSselect$informedconsent <- to_factor(AEGSselect$informedconsent)

AEGSselect.CEA$GWAS <- to_factor(AEGSselect.CEA$GWAS)
AEGSselect.CEA$CHIP <- to_factor(AEGSselect.CEA$CHIP)
AEGSselect.CEA$PCA <- to_factor(AEGSselect.CEA$PCA)
AEGSselect.CEA$SAMPLE_TYPE <- to_factor(AEGSselect.CEA$SAMPLE_TYPE)
AEGSselect.CEA$informedconsent <- to_factor(AEGSselect.CEA$informedconsent)


cat("===========================================================================================\n")
===========================================================================================
cat("CREATE BASELINE TABLE\n")
CREATE BASELINE TABLE
# Baseline table variables
basetable_vars = c("Hospital", 
                   "Age", "Gender", 
                   "TC_final", "LDL_final", "HDL_final", "TG_final", 
                   "systolic", "diastoli", "GFR_MDRD", "BMI", 
                   "KDOQI", "BMI_WHO", 
                   "SmokerCurrent", "eCigarettes", "ePackYearsSmoking",
                   "DiabetesStatus", "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", 
                   "Hypertension.drugs", "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
                   "Stroke_Dx", "sympt", "Symptoms.5G", "restenos",
                   "EP_composite", "EP_composite_time",
                   "macmean0", "smcmean0", "Macrophages.bin", "SMC.bin", "neutrophils", "Mast_cells_plaque", "vessel_density_averaged",
                   "IPH.bin", 
                   "Calc.bin", "Collagen.bin", 
                   "Fat.bin_10", "Fat.bin_40", "OverallPlaquePhenotype", "Plaque_Vulnerability_Index",
                   "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                  "GWAS", "CHIP", "PCA")

basetable_bin = c("Gender", 
                  "KDOQI", "BMI_WHO", 
                  "SmokerCurrent", 
                  "DiabetesStatus", "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", 
                  "Hypertension.drugs", "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
                  "Stroke_Dx", "sympt", "Symptoms.5G", "restenos",
                  "EP_composite", "Macrophages.bin", "SMC.bin",
                  "IPH.bin", 
                  "Calc.bin", "Collagen.bin", 
                  "Fat.bin_10", "Fat.bin_40", "OverallPlaquePhenotype", "Plaque_Vulnerability_Index",
                  "GWAS", "CHIP", "PCA")

basetable_bin
 [1] "Gender"                      "KDOQI"                       "BMI_WHO"                     "SmokerCurrent"               "DiabetesStatus"              "Hypertension.selfreport"    
 [7] "Hypertension.selfreportdrug" "Hypertension.composite"      "Hypertension.drugs"          "Med.anticoagulants"          "Med.all.antiplatelet"        "Med.Statin.LLD"             
[13] "Stroke_Dx"                   "sympt"                       "Symptoms.5G"                 "restenos"                    "EP_composite"                "Macrophages.bin"            
[19] "SMC.bin"                     "IPH.bin"                     "Calc.bin"                    "Collagen.bin"                "Fat.bin_10"                  "Fat.bin_40"                 
[25] "OverallPlaquePhenotype"      "Plaque_Vulnerability_Index"  "GWAS"                        "CHIP"                        "PCA"                        
basetable_con = basetable_vars[!basetable_vars %in% basetable_bin]
basetable_con
 [1] "Hospital"                "Age"                     "TC_final"                "LDL_final"               "HDL_final"               "TG_final"                "systolic"               
 [8] "diastoli"                "GFR_MDRD"                "BMI"                     "eCigarettes"             "ePackYearsSmoking"       "EP_composite_time"       "macmean0"               
[15] "smcmean0"                "neutrophils"             "Mast_cells_plaque"       "vessel_density_averaged" "SMC_rankNorm"            "MAC_rankNorm"            "Neutrophils_rankNorm"   
[22] "MastCells_rankNorm"      "VesselDensity_rankNorm" 

All Athero-Express Genomics Study data (n = 2,011), compared to the remaining, _un_genotyped Athero-Express Biobank Study.

cat("\n===========================================================================================\n")
cat("DISPLAY BASELINE TABLE\n")

AEGSselect.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                         # factorVars = basetable_bin,
                                         strata = "GWAS",
                                         data = AEGSselect, includeNA = TRUE), 
                          nonnormal = c(), missing = TRUE,
                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
                          format = "pf", 
                          contDigits = 3)[,1:6]

Baseline of the valid, CEA and genotyped data.

AEGSselect.CEA.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                         # factorVars = basetable_bin,
                                         strata = "Gender",
                                         data = AEGSselect.CEA, includeNA = TRUE), 
                          nonnormal = c(), missing = TRUE,
                          quote = FALSE, noSpaces = FALSE, showAllLevels = TRUE, explain = TRUE, 
                          format = "pf", 
                          contDigits = 3)[,1:6]

Athero-Express Genomics Study: writing

Let’s save the baseline characteristics of the Athero-Express Genomics Study.

# Write basetable
require(openxlsx)

write.xlsx(file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AEGS.BaselineTable.xlsx"), 
           AEGSselect.tableOne, 
           rowNames = TRUE, 
           colNames = TRUE, 
           sheetName = "AEGS_Baseline", overwrite = TRUE)

write.xlsx(file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AEGS.CEA.BaselineTable.xlsx"), 
           AEGSselect.CEA.tableOne, 
           rowNames = TRUE, 
           colNames = TRUE, 
           sheetName = "AEGS_Baseline_full", overwrite = TRUE)

SampleLists

Autosomal data.

We are ready to make a sampleList for use with the imputed data.

require(openxlsx)

temp <- subset(AEGS,
               GWAS == "genotyped",
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", # ID_2 is the order of samples!
                          "QC2018_FINAL", "QC2018_FILTER", "OriginalOrder_postMichImp_QC",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE", "PCA",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "Calc.bin", "Collagen.bin", 
                          "Fat.bin_10", "Fat.bin_40", "IPH.bin", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                          "Plaque_Vulnerability_Index")) # Select some phenotype of interest
dim(temp)
[1] 2124   36
# Fix things
attach(temp)

temp[,"Calcification"] <- NA
temp$Calcification[Calc.bin == "no/minor"] <- "control"
temp$Calcification[Calc.bin == "moderate/heavy"] <- "case"

temp[,"Collagen"] <- NA
temp$Collagen[Collagen.bin == "no/minor"] <- "control"
temp$Collagen[Collagen.bin == "moderate/heavy"] <- "case"

temp[,"Fat10"] <- NA
temp$Fat10[Fat.bin_10 == "<10%"] <- "control"
temp$Fat10[Fat.bin_10 == ">10%"] <- "case"

temp[,"Fat40"] <- NA
temp$Fat40[Fat.bin_40 == "<40%"] <- "control"
temp$Fat40[Fat.bin_40 == ">40%"] <- "case"

temp[,"IPH"] <- NA
temp$IPH[IPH.bin == "no"] <- "control"
temp$IPH[IPH.bin == "yes"] <- "case"

temp[,"PVI"] <- NA
temp$PVI[Plaque_Vulnerability_Index == "0"] <- "PVI_cat0"
temp$PVI[Plaque_Vulnerability_Index == "1"] <- "PVI_cat1"
temp$PVI[Plaque_Vulnerability_Index == "2"] <- "PVI_cat2"
temp$PVI[Plaque_Vulnerability_Index == "3"] <- "PVI_cat3"
temp$PVI[Plaque_Vulnerability_Index == "4"] <- "PVI_cat4"
temp$PVI[Plaque_Vulnerability_Index == "5"] <- "PVI_cat5"

temp$Plaque_Vulnerability_Index <- temp$PVI
temp$PVI <- NULL

detach(temp)

# Making selection variable
attach(temp)
temp[,"SELECTION"] <- "not_selected"
temp$SELECTION[(QC2018_FILTER=="passed" | QC2018_FILTER=="family_keep") & (STUDY_TYPE=="CEA" & PCA=="EUR")] <- "selected"
detach(temp)
table(temp$SELECTION, temp$QC2018_FILTER)
              
               family_discard family_keep issue passed
  not_selected             23           0    40    153
  selected                  0          21     0   1887
table(temp$SELECTION, temp$STUDY_TYPE)
              
                CEA  FEA Other
  not_selected   94  109    12
  selected     1908    0     0
table(temp$SELECTION, temp$PCA)
              
                EUR nonEUR
  not_selected  167     45
  selected     1908      0
table(temp$Plaque_Vulnerability_Index)

PVI_cat0 PVI_cat1 PVI_cat2 PVI_cat3 PVI_cat4 PVI_cat5 
     485      320      422      479      221       84 

AEGS123_sample.list <- temp[order(temp$OriginalOrder_postMichImp_QC),]

AEGS123_sample.list$missing <- 0

sample_file_aegs <- dplyr::select(AEGS123_sample.list,
                                  ID_1, ID_2, missing, # ID_2 is the order of samples - that way we always know what the order should be
                                  UPID, STUDY_NUMBER, 
                                  QC2018_FINAL, QC2018_FILTER, SELECTION,
                                  AEGS_type, CHIP, STUDY_TYPE, SAMPLE_TYPE, PCA,
                                  PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10,
                                  Sex, Age, ORyear, 
                                  Calcification, Collagen, 
                                  Fat10, Fat40, IPH, 
                                  SMC_rankNorm, MAC_rankNorm, Neutrophils_rankNorm, MastCells_rankNorm, VesselDensity_rankNorm,
                                  Plaque_Vulnerability_Index)  %>%
  mutate_if(is.numeric, as.character) %>%
  mutate(SAMPLE_TYPE = gsub(' ', '_', SAMPLE_TYPE)) %>%
  add_row(.before = 1, 
          ID_1 = "0", ID_2 = "0", missing = "0", 
          UPID = "D", STUDY_NUMBER = "C",
          QC2018_FINAL = "D", QC2018_FILTER = "D", SELECTION = "D",
          AEGS_type = "D", CHIP = "D", STUDY_TYPE = "D", SAMPLE_TYPE = "D", PCA = "D",
          PC1 = "C", PC2 = "C", PC3 = "C", PC4 = "C", PC5 = "C", PC6 = "C", PC7 = "C", PC8 = "C", PC9 = "C", PC10 = "C",
          Sex = "D", Age = "C", ORyear = "C", 
          Calcification = "B", Collagen = "B", 
          Fat10 = "B", Fat40 = "B", IPH = "B", 
          SMC_rankNorm = "P", MAC_rankNorm = "P", Neutrophils_rankNorm = "P", MastCells_rankNorm = "P", VesselDensity_rankNorm = "P",
          Plaque_Vulnerability_Index = "P") %>% ## identifiers: index for these is 1, and all base variables have 0 as identifier
  print()
dim(sample_file_aegs)
[1] 2125   37
fwrite(sample_file_aegs,
       file = paste0(SNP_loc, "/",Today,".",PROJECTNAME,".AEGS123.sample"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = TRUE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=2125 args.ncol=37 eolLen=1
maxLineLen=862. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (true) ... done in 0.048s
Writing 2125 rows in 1 batches of 2125 rows (each buffer size 8MB, showProgress=1, nth=1)
require(DT)
DT::datatable(sample_file_aegs, caption = "AEGS: final sample list of genotyped AE patients after quality control.", rownames = FALSE)
Warning in instance$preRenderHook(instance) :
  It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
Warning in instance$preRenderHook(instance) :
  It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
rm(temp, temp2, temp3)
Warning in rm(temp, temp2, temp3) : object 'temp2' not found
Warning in rm(temp, temp2, temp3) : object 'temp3' not found

X-chromosome data

The X-chromosome data is taken from previously imputed data based on 1000G phase 3 (version 5) and GoNL5. For some reason, imputing on the Michigan Imputation Server was not successful (ACTION point).

Here we load in the sample files for the three datasets of the X chromosomal data. We should:

  • filter out samples that did not pass quality control, ending up with 2,124 sample
  • re-order the data to fit the other autosomal data.

AEGS123_chrX <- fread(paste0(MICHIMP_loc, "/_chr23_1kg_gonl5/aegs.raw.1kg_gonl5.chr23.mappings.txt"))
names(AEGS123_chrX)[names(AEGS123_chrX) == "ID_1"] <- "SampleID_postImpChrX"

AEGS123_AllChr <- merge(AEGS123_chrX, sample_file_aegs, by.x = "SampleID_postMichImp", by.y = "ID_1", 
                        all.x = TRUE, 
                        sort = FALSE)

names(AEGS123_AllChr)[names(AEGS123_AllChr) == "ID_2.y"] <- "ID_2"
names(AEGS123_AllChr)[names(AEGS123_AllChr) == "STUDY_TYPE.y"] <- "STUDY_TYPE"
names(AEGS123_AllChr)[names(AEGS123_AllChr) == "SampleID_postMichImp"] <- "ID_1"
AEGS123_AllChr$missing.x <- NULL
AEGS123_AllChr$missing.y <- NULL
AEGS123_AllChr$STUDY_TYPE.x <- NULL
AEGS123_AllChr$ID_2.x <- NULL

dim(AEGS123_AllChr)
[1] 2176   42
str(AEGS123_AllChr)
Classes 'data.table' and 'data.frame':  2176 obs. of  42 variables:
 $ ID_1                      : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ SampleID_postImpChrX      : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ MappingID                 : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ FID_forQC                 : chr  "0" "UPID00126" "UPID01799" "UPID01890" ...
 $ IID_forQC                 : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ SampleID_postQC           : chr  "0" "UPID00126-UPID00126-A318-0034" "UPID01799-UPID01799-A318-0492" "UPID01890-UPID01890-A318-0151" ...
 $ ChrX_Order                : int  0 1 2 NA 3 4 5 6 NA 7 ...
 $ ID_2                      : chr  "0" "22" "325" NA ...
 $ UPID                      : chr  "D" NA NA NA ...
 $ STUDY_NUMBER              : chr  "C" "901" "1164" NA ...
 $ QC2018_FINAL              : chr  "D" NA NA NA ...
 $ QC2018_FILTER             : chr  "D" "passed" "passed" NA ...
 $ SELECTION                 : chr  "D" "selected" "selected" NA ...
 $ AEGS_type                 : chr  "D" "AEGS1" "AEGS1" NA ...
 $ CHIP                      : chr  "D" "AffySNP5" "AffySNP5" NA ...
 $ STUDY_TYPE                : chr  "D" "CEA" "CEA" NA ...
 $ SAMPLE_TYPE               : chr  "D" "plaque" "plaque" NA ...
 $ PCA                       : chr  "D" "EUR" "EUR" NA ...
 $ PC1                       : chr  "C" "-0.0316" "-0.0131" NA ...
 $ PC2                       : chr  "C" "0.0161" "-0.0069" NA ...
 $ PC3                       : chr  "C" "-0.01" "0.0383" NA ...
 $ PC4                       : chr  "C" "-0.0131" "-0.005" NA ...
 $ PC5                       : chr  "C" "0.0059" "0.0078" NA ...
 $ PC6                       : chr  "C" "-0.0283" "0.0243" NA ...
 $ PC7                       : chr  "C" "-2e-04" "-0.018" NA ...
 $ PC8                       : chr  "C" "0.0033" "0.0022" NA ...
 $ PC9                       : chr  "C" "-0.0317" "-0.0154" NA ...
 $ PC10                      : chr  "C" "-0.0054" "0.007" NA ...
 $ Sex                       : chr  "D" "F" "M" NA ...
 $ Age                       : chr  "C" NA NA NA ...
 $ ORyear                    : chr  "C" NA NA NA ...
 $ Calcification             : chr  "B" NA NA NA ...
 $ Collagen                  : chr  "B" NA NA NA ...
 $ Fat10                     : chr  "B" NA NA NA ...
 $ Fat40                     : chr  "B" NA NA NA ...
 $ IPH                       : chr  "B" NA NA NA ...
 $ SMC_rankNorm              : chr  "P" NA NA NA ...
 $ MAC_rankNorm              : chr  "P" NA NA NA ...
 $ Neutrophils_rankNorm      : chr  "P" NA NA NA ...
 $ MastCells_rankNorm        : chr  "P" NA NA NA ...
 $ VesselDensity_rankNorm    : chr  "P" NA NA NA ...
 $ Plaque_Vulnerability_Index: chr  "P" NA NA NA ...
 - attr(*, ".internal.selfref")=<externalptr> 

This seems fine, let’s filter; we can use this file to filter the genetic data. And we create another file to re-order the data.


AEGS123_AllChrQC <- subset(AEGS123_AllChr,
               !is.na(QC2018_FILTER),
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", "SampleID_postImpChrX",
                          "QC2018_FINAL", "QC2018_FILTER", "SELECTION",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "Calcification", "Collagen", 
                          "Fat10", "Fat40", "IPH", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                          "Plaque_Vulnerability_Index"))

AEGS123_AllChrQC_reorder <-AEGS123_AllChrQC[order(AEGS123_AllChrQC$ID_2),] # remember: ID_2 is the order of samples

AEGS123_AllChrQC_filtered <- subset(AEGS123_AllChr,
               is.na(QC2018_FILTER),
               select = c("ID_1", "ID_2", "UPID", "STUDY_NUMBER", "SampleID_postImpChrX",
                          "QC2018_FINAL", "QC2018_FILTER", "SELECTION",
                          "AEGS_type", "CHIP", "STUDY_TYPE", "SAMPLE_TYPE",
                          "PC1", "PC2", "PC3", "PC4", "PC5",
                          "PC6", "PC7", "PC8", "PC9", "PC10",
                          "Sex", "Age", "ORyear", 
                          "Calcification", "Collagen", 
                          "Fat10", "Fat40", "IPH", 
                          "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
                          "Plaque_Vulnerability_Index"))

fwrite(AEGS123_AllChrQC_reorder,
       file = paste0(SNP_loc, "/",Today,".",PROJECTNAME,".AEGS123.chrX.sample"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = TRUE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=2013 args.ncol=36 eolLen=1
maxLineLen=929. Found in 0.001s
Writing bom (false), yaml (0 characters) and column names (true) ... done in 0.002s
Writing 2013 rows in 1 batches of 2013 rows (each buffer size 8MB, showProgress=1, nth=1)
require(DT)
DT::datatable(AEGS123_AllChrQC, caption = "AEGS: final sample list of genotyped AE patients after quality control (chromosome X).", rownames = FALSE)
Warning in instance$preRenderHook(instance) :
  It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
Warning in instance$preRenderHook(instance) :
  It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html

GWASToolKit preparation

VariantLists: top SNPs

Here we create a variantlist.txt file used by GWASToolKit for analysis.These are the variants with LD r2 => 0.6 around each of the 15 top SNPs associated with CAC.

variant_list

temp <- subset(variant_list, select = c("VariantID", "Chr", "BP"))

fwrite(temp,
       file = paste0(SNP_loc, "/variantlist.txt"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = FALSE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 5 5 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=898 args.ncol=3 eolLen=1
maxLineLen=144. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (false) ... done in 0.009s
Writing 898 rows in 1 batches of 898 rows (each buffer size 8MB, showProgress=1, nth=1)
rm(temp)

VariantLists: Credible Set

Here we create a crediblesetlist.txt file used by GWASToolKit for analysis.These are the variants in the 95% credible set of causal variants for the 15 top SNPs associated with CAC.

credset_list

temp <- subset(credset_list, select = c("VariantID", "Chr", "BP"))

fwrite(temp,
       file = paste0(SNP_loc, "/crediblesetlist.txt"),
       na = "NA", sep = "\t", quote = FALSE,
       row.names = FALSE, col.names = FALSE,
       showProgress = TRUE, verbose = TRUE)
This installation of data.table has not been compiled with OpenMP support.
  omp_get_num_procs()            1
  R_DATATABLE_NUM_PROCS_PERCENT  unset (default 50)
  R_DATATABLE_NUM_THREADS        unset
  R_DATATABLE_THROTTLE           unset (default 1024)
  omp_get_thread_limit()         1
  omp_get_max_threads()          1
  OMP_THREAD_LIMIT               unset
  OMP_NUM_THREADS                1
  RestoreAfterFork               true
  data.table is using 1 threads with throttle==1024. See ?setDTthreads.
No list columns are present. Setting sep2='' otherwise quote='auto' would quote fields containing sep2.
Column writers: 12 5 5 
args.doRowNames=0 args.rowNames=0 doQuote=0 args.nrow=103 args.ncol=3 eolLen=1
maxLineLen=144. Found in 0.000s
Writing bom (false), yaml (0 characters) and column names (false) ... done in 0.031s
Writing 103 rows in 1 batches of 103 rows (each buffer size 8MB, showProgress=1, nth=1)
rm(temp)

Covariates

Here we create a covariates.txt file used by GWASToolKit for analysis.

library(tidyverse)
# for 'overall' analyses
c("Age Sex PC1 PC2 CHIP ORyear") %>% write_lines(paste0(SNP_loc, "/covariates.txt"))

# for sex-specific analyses
c("Age PC1 PC2 CHIP ORyear") %>% write_lines(paste0(SNP_loc, "/covariates.sex.txt"))

Phenotypes

Here we create a phenotypes.txt file used by GWASToolKit for analysis.

library(tidyverse)
c("Calcification", "Collagen", "Fat10", "Fat40", "IPH", "SMC_rankNorm", "MAC_rankNorm", "Neutrophils_rankNorm", "MastCells_rankNorm", "VesselDensity_rankNorm",
  "Plaque_Vulnerability_Index") %>% write_lines(paste0(SNP_loc, "/phenotypes.txt"))

c("Plaque_Vulnerability_Index") %>% write_lines(paste0(SNP_loc, "/phenotypes.pvi.txt"))

Session information


Version:      v1.0.6
Last update:  2021-12-03
Written by:   Sander W. van der Laan (s.w.vanderlaan-2[at]umcutrecht.nl).
Description:  Script to get some Athero-Express Biobank Study baseline characteristics.
Minimum requirements: R version 3.4.3 (2017-06-30) -- 'Single Candle', Mac OS X El Capitan

Changes log
* v1.0.6 Update code and fix coding of plaque vulnerability index (PVI) to work with SNPTEST.
* v1.0.5 Update analysis with credible set SNPs.
* v1.0.4 Update with PVI. Removed PCSK9.
* v1.0.3 Update to the gene list.
* v1.0.2 Updated baseline characteristics information. Update GWASToolKit preparation. Added more candidate SNPs to look at. Updated some variable names. 
* v1.0.1 Add an additional phenotype.
* v1.0.0 Initial version. Fixed baseline table, added codes, and results. Created sample-files.

sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Monterey 12.0.1

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] grid      tools     stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] gridExtra_2.3        plyr_1.8.6           labelled_2.9.0       openxlsx_4.2.4       UpSetR_1.4.0         ggpubr_0.4.0.999     forestplot_2.0.1     checkmate_2.0.0      magrittr_2.0.1      
[10] pheatmap_1.0.12      devtools_2.4.2       usethis_2.1.3        BlandAltmanLeh_0.3.1 tableone_0.13.0      haven_2.4.3          eeptools_1.2.4       DT_0.20              knitr_1.36          
[19] forcats_0.5.1        stringr_1.4.0        purrr_0.3.4          tibble_3.1.6         ggplot2_3.3.5        tidyverse_1.3.1      data.table_1.14.2    naniar_0.6.1         tidyr_1.1.4         
[28] dplyr_1.0.7          optparse_1.7.1       readr_2.1.0         

loaded via a namespace (and not attached):
  [1] estimability_1.3            rappdirs_0.3.3              rtracklayer_1.52.1          scattermore_0.7             coda_0.19-4                 SeuratObject_4.0.4          visdat_0.5.3               
  [8] bit64_4.0.5                 irlba_2.3.3                 multcomp_1.4-17             DelayedArray_0.18.0         rpart_4.1-15                KEGGREST_1.32.0             RCurl_1.98-1.5             
 [15] AnnotationFilter_1.16.0     generics_0.1.1              BiocGenerics_0.38.0         GenomicFeatures_1.44.2      callr_3.7.0                 cowplot_1.1.1               TH.data_1.1-0              
 [22] RSQLite_2.2.8               RANN_2.6.1                  proxy_0.4-26                future_1.23.0               tzdb_0.2.0                  bit_4.0.4                   lubridate_1.8.0            
 [29] spatstat.data_2.1-0         xml2_1.3.2                  httpuv_1.6.3                SummarizedExperiment_1.22.0 assertthat_0.2.1            xfun_0.28                   jquerylib_0.1.4            
 [36] hms_1.1.1                   evaluate_0.14               promises_1.2.0.1            fansi_0.5.0                 restfulr_0.0.13             progress_1.2.2              readxl_1.3.1               
 [43] dbplyr_2.1.1                igraph_1.2.9                DBI_1.1.1                   htmlwidgets_1.5.4           spatstat.geom_2.3-0         stats4_4.1.2                ellipsis_0.3.2             
 [50] crosstalk_1.2.0             backports_1.4.0             survey_4.1-1                insight_0.14.5              biomaRt_2.48.3              deldir_1.0-6                MatrixGenerics_1.4.3       
 [57] vctrs_0.3.8                 Biobase_2.52.0              remotes_2.4.1               ensembldb_2.16.4            ROCR_1.0-11                 sjlabelled_1.1.8            abind_1.4-5                
 [64] cachem_1.0.6                withr_2.4.2                 vroom_1.5.6                 vcd_1.4-9                   emmeans_1.7.0               sctransform_0.3.2           GenomicAlignments_1.28.0   
 [71] prettyunits_1.1.1           getopt_1.20.3               goftest_1.2-3               cluster_2.1.2               lazyeval_0.2.2              crayon_1.4.2                labeling_0.4.2             
 [78] pkgconfig_2.0.3             GenomeInfoDb_1.28.4         nlme_3.1-153                pkgload_1.2.3               ProtGenerics_1.24.0         rlang_0.4.12                globals_0.14.0             
 [85] lifecycle_1.0.1             miniUI_0.1.1.1              sandwich_3.0-1              filelock_1.0.2              BiocFileCache_2.0.0         modelr_0.1.8                cellranger_1.1.0           
 [92] rprojroot_2.0.2             polyclip_1.10-0             matrixStats_0.61.0          lmtest_0.9-39               datawizard_0.2.1            Matrix_1.3-4                carData_3.0-4              
 [99] boot_1.3-28                 zoo_1.8-9                   reprex_2.0.1                ggridges_0.5.3              processx_3.5.2              png_0.1-7                   viridisLite_0.4.0          
[106] rjson_0.2.20                parameters_0.15.0           bitops_1.0-7                KernSmooth_2.23-20          pander_0.6.4                Biostrings_2.60.2           blob_1.2.2                 
[113] maptools_1.1-2              arm_1.12-2                  parallelly_1.29.0           rstatix_0.7.0               ggeffects_1.1.1             S4Vectors_0.30.2            ggsignif_0.6.3             
[120] scales_1.1.1                memoise_2.0.1               ica_1.0-2                   zlibbioc_1.38.0             compiler_4.1.2              BiocIO_1.2.0                RColorBrewer_1.1-2         
[127] lme4_1.1-27.1               fitdistrplus_1.1-6          snakecase_0.11.0            Rsamtools_2.8.0             cli_3.1.0                   XVector_0.32.0              listenv_0.8.0              
[134] patchwork_1.1.0.9000        pbapply_1.5-0               ps_1.6.0                    MASS_7.3-54                 mgcv_1.8-38                 tidyselect_1.1.1            stringi_1.7.6              
[141] mitools_2.4                 yaml_2.2.1                  ggrepel_0.9.1               sass_0.4.0                  future.apply_1.8.1          parallel_4.1.2              rstudioapi_0.13            
[148] foreign_0.8-81              farver_2.1.0                Rtsne_0.15                  sjPlot_2.8.10               digest_0.6.28               BiocManager_1.30.16         shiny_1.7.1                
[155] Rcpp_1.0.7                  GenomicRanges_1.44.0        car_3.0-12                  broom_0.7.10                performance_0.8.0           later_1.3.0                 RcppAnnoy_0.0.19           
[162] httr_1.4.2                  AnnotationDbi_1.54.1        effectsize_0.5              sjstats_0.18.1              colorspace_2.0-2            rvest_1.0.2                 XML_3.99-0.8               
[169] fs_1.5.0                    tensor_1.5                  reticulate_1.22             IRanges_2.26.0              splines_4.1.2               uwot_0.1.10                 spatstat.utils_2.2-0       
[176] sp_1.4-6                    plotly_4.10.0               sessioninfo_1.2.1           xtable_1.8-4                jsonlite_1.7.2              nloptr_1.2.2.3              testthat_3.1.0             
[183] R6_2.5.1                    pillar_1.6.4                htmltools_0.5.2             mime_0.12                   glue_1.5.0                  fastmap_1.1.0               minqa_1.2.4                
[190] BiocParallel_1.26.2         class_7.3-19                codetools_0.2-18            pkgbuild_1.2.0              mvtnorm_1.1-3               utf8_1.2.2                  bslib_0.3.1                
[197] lattice_0.20-45             spatstat.sparse_2.0-0       curl_4.3.2                  leiden_0.3.9                zip_2.2.0                   survival_3.2-13             rmarkdown_2.11             
[204] desc_1.4.0                  munsell_0.5.0               e1071_1.7-9                 GenomeInfoDbData_1.2.6      sjmisc_2.8.7                reshape2_1.4.4              gtable_0.3.0               
[211] bayestestR_0.11.5           spatstat.core_2.3-2         Seurat_4.0.5               

Saving environment

save.image(paste0(PROJECT_loc, "/",Today,".",PROJECTNAME,".results.RData"))
© 1979-2021 Sander W. van der Laan | s.w.vanderlaan[at]gmail.com | swvanderlaan.github.io.
LS0tCnRpdGxlOiAiQXNzb2NpYXRpb24gb2YgQ0FDIHN1c2NlcHRpYmlsaXR5IGxvY2kgcGxhcXVlIGNoYXJhY3RlcmlzdGljcy4iCmF1dGhvcjogIltTYW5kZXIgVy4gdmFuIGRlciBMYWFuLCBQaERdKGh0dHBzOi8vc3d2YW5kZXJsYWFuLmdpdGh1Yi5pbykgfCBAc3d2YW5kZXJsYWFuIHwgcy53LnZhbmRlcmxhYW5AZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY2FjaGU6IHllcwogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2xsYXBzZTogeWVzCiAgICBkZl9wcmludDogcGFnZWQKICAgIGZpZy5hbGlnbjogY2VudGVyCiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBmaWdfaGVpZ2h0OiA2CiAgICBmaWdfcmV0aW5hOiAyCiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiBsdW1lbgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBubwogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMKbWFpbmZvbnQ6IEFyaWFsCnN1YnRpdGxlOiAiQSAnZHJ1Z2dhYmxlLU1JLXRhcmdldHMnIHByb2plY3QiCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7ciBnbG9iYWxfb3B0aW9ucywgaW5jbHVkZSA9IEZBTFNFfQojIGZ1cnRoZXIgZGVmaW5lIHNvbWUga25pdHItb3B0aW9ucy4Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLnBhdGggPSAnRmlndXJlcy8nLCAKICAgICAgICAgICAgICAgICAgICAgIHd3YXJuaW5nID0gVFJVRSwgIyBzaG93IHdhcm5pbmdzIGR1cmluZyBjb2RlYm9vayBnZW5lcmF0aW9uCiAgbWVzc2FnZSA9IFRSVUUsICMgc2hvdyBtZXNzYWdlcyBkdXJpbmcgY29kZWJvb2sgZ2VuZXJhdGlvbgogIGVycm9yID0gVFJVRSwgIyBkbyBub3QgaW50ZXJydXB0IGNvZGVib29rIGdlbmVyYXRpb24gaW4gY2FzZSBvZiBlcnJvcnMsCiAgICAgICAgICAgICAgICAjIHVzdWFsbHkgYmV0dGVyIGZvciBkZWJ1Z2dpbmcKICBlY2hvID0gVFJVRSwgICMgc2hvdyBSIGNvZGUKICAgICAgICAgICAgICAgICAgICAgIGV2YWwgPSBUUlVFKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfbWluaW1hbCgpKQpwYW5kZXI6OnBhbmRlck9wdGlvbnMoInRhYmxlLnNwbGl0LnRhYmxlIiwgSW5mKQpgYGAKCiMgU2V0dXAKV2Ugd2lsbCBjbGVhbiB0aGUgZW52aXJvbm1lbnQsIHNldHVwIHRoZSBsb2NhdGlvbnMsIGRlZmluZSBjb2xvcnMsIGFuZCBjcmVhdGUgYSBkYXRlc3RhbXAuCgpfQ2xlYW4gdGhlIGVudmlyb25tZW50Ll8KYGBge3IgZWNobyA9IEZBTFNFfQojIHJtKGxpc3QgPSBscygpKQpgYGAKCl9TZXQgbG9jYXRpb25zIGFuZCB3b3JraW5nIGRpcmVjdG9yaWVzLi4uXwpgYGB7ciBMb2NhbFN5c3RlbSwgZWNobyA9IEZBTFNFfQojIyMgT3BlcmF0aW5nIFN5c3RlbSBWZXJzaW9uCgojIyMgTWFjQm9vayBBaXIKUk9PVF9sb2MgPSAiL1VzZXJzL3NsYWFuMy9PbmVEcml2ZSAtIFVNQyBVdHJlY2h0IgpTVE9SQUdFX2xvYyA9ICIvVm9sdW1lcy9MYUNpZS8iCkdFTk9NSUNfbG9jID0gcGFzdGUwKFJPT1RfbG9jLCAiL0dlbm9taWNzIikKQUVEQl9sb2MgPSBwYXN0ZTAoR0VOT01JQ19sb2MsICIvQXRoZXJvLUV4cHJlc3MvQUUtQUFBX0dTX0RCcyIpCkxBQl9sb2MgPSBwYXN0ZTAoR0VOT01JQ19sb2MsICIvTGFiQnVzaW5lc3MiKQoKUExJTktfbG9jPXBhc3RlMChTVE9SQUdFX2xvYywiL1BMSU5LIikKQUVHU1FDX2xvYyA9ICBwYXN0ZTAoUExJTktfbG9jLCAiL19BRV9PUklHSU5BTFMvQUVHU19DT01CSU5FRF9RQzIwMTgiKQpNSUNISU1QX2xvYz1wYXN0ZTAoUExJTktfbG9jLCIvX0FFX09SSUdJTkFMUy9BRUdTX0NPTUJJTkVEX0VBR0xFMl8xMDAwR3AzdjVIUkNyMTEiKQoKUFJPSkVDVF9sb2MgPSBwYXN0ZTAoUExJTktfbG9jLCAiL2FuYWx5c2VzL2xvb2t1cHMvQUVfMjAyMDA1MTJfQ09MX01LQVZPVVNJX01CT1NfQ0hBUkdFXzEwMDBHX0NBQyIpCgojIHVzZSB0aGlzIGlmIHRoZXJlIGlzIHJlbGV2YW50IGluZm9ybWF0aW9uIGhlcmUuClRBUkdFVF9sb2MgPSBwYXN0ZTAoR0VOT01JQ19sb2MsICIvQXRoZXJvLUV4cHJlc3MvRm9ybXMvMjAyMC9BRV8yMDIwMDUxMl9DT0xfTUtBVk9VU0lfTUJPU19DSEFSR0VfMTAwMEdfQ0FDIikKCiMjIyBTT01FIFZBUklBQkxFUyBXRSBORUVEIERPV04gVEhFIExJTkUKVFJBSVRfT0ZfSU5URVJFU1QgPSAiQ0FDIiAjIFBoZW5vdHlwZQpQUk9KRUNUTkFNRSA9ICJDQUMiCgpjYXQoIlxuQ3JlYXRlIGEgbmV3IGFuYWx5c2lzIGRpcmVjdG9yeS4uLlxuIikKaWZlbHNlKCFkaXIuZXhpc3RzKGZpbGUucGF0aChQUk9KRUNUX2xvYywgIi8iLFBST0pFQ1ROQU1FKSksIAogICAgICAgZGlyLmNyZWF0ZShmaWxlLnBhdGgoUFJPSkVDVF9sb2MsICIvIixQUk9KRUNUTkFNRSkpLCAKICAgICAgIEZBTFNFKQpBTkFMWVNJU19sb2MgPSBwYXN0ZTAoUFJPSkVDVF9sb2MsIi8iLFBST0pFQ1ROQU1FKQoKaWZlbHNlKCFkaXIuZXhpc3RzKGZpbGUucGF0aChBTkFMWVNJU19sb2MsICIvUExPVFMiKSksIAogICAgICAgZGlyLmNyZWF0ZShmaWxlLnBhdGgoQU5BTFlTSVNfbG9jLCAiL1BMT1RTIikpLCAKICAgICAgIEZBTFNFKQpQTE9UX2xvYyA9IHBhc3RlMChBTkFMWVNJU19sb2MsIi9QTE9UUyIpCgppZmVsc2UoIWRpci5leGlzdHMoZmlsZS5wYXRoKFBMT1RfbG9jLCAiL1FDIikpLCAKICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKFBMT1RfbG9jLCAiL1FDIikpLCAKICAgICAgIEZBTFNFKQpRQ19sb2MgPSBwYXN0ZTAoUExPVF9sb2MsIi9RQyIpCgppZmVsc2UoIWRpci5leGlzdHMoZmlsZS5wYXRoKEFOQUxZU0lTX2xvYywgIi9PVVRQVVQiKSksIAogICAgICAgZGlyLmNyZWF0ZShmaWxlLnBhdGgoQU5BTFlTSVNfbG9jLCAiL09VVFBVVCIpKSwgCiAgICAgICBGQUxTRSkKT1VUX2xvYyA9IHBhc3RlMChBTkFMWVNJU19sb2MsICIvT1VUUFVUIikKCmlmZWxzZSghZGlyLmV4aXN0cyhmaWxlLnBhdGgoQU5BTFlTSVNfbG9jLCAiL0JBU0VMSU5FIikpLCAKICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKEFOQUxZU0lTX2xvYywgIi9CQVNFTElORSIpKSwgCiAgICAgICBGQUxTRSkKQkFTRUxJTkVfbG9jID0gcGFzdGUwKEFOQUxZU0lTX2xvYywgIi9CQVNFTElORSIpCgppZmVsc2UoIWRpci5leGlzdHMoZmlsZS5wYXRoKFBST0pFQ1RfbG9jLCAiL1NOUCIpKSwgCiAgICAgICBkaXIuY3JlYXRlKGZpbGUucGF0aChQUk9KRUNUX2xvYywgIi9TTlAiKSksIAogICAgICAgRkFMU0UpClNOUF9sb2MgPSBwYXN0ZTAoUFJPSkVDVF9sb2MsICIvU05QIikKCnNldHdkKHBhc3RlMChQUk9KRUNUX2xvYykpCmdldHdkKCkKbGlzdC5maWxlcygpCgpgYGAKCl8uLi4gYSBwYWNrYWdlLWluc3RhbGxhdGlvbiBmdW5jdGlvbiAuLi5fCmBgYHtyIEZ1bmN0aW9uOiBpbnN0YWxsYXRpb25zfQppbnN0YWxsLnBhY2thZ2VzLmF1dG8gPC0gZnVuY3Rpb24oeCkgeyAKICB4IDwtIGFzLmNoYXJhY3RlcihzdWJzdGl0dXRlKHgpKSAKICBpZihpc1RSVUUoeCAlaW4lIC5wYWNrYWdlcyhhbGwuYXZhaWxhYmxlID0gVFJVRSkpKSB7IAogICAgZXZhbChwYXJzZSh0ZXh0ID0gc3ByaW50ZigicmVxdWlyZShcIiVzXCIpIiwgeCkpKQogIH0gZWxzZSB7IAogICAgIyBVcGRhdGUgaW5zdGFsbGVkIHBhY2thZ2VzIC0gdGhpcyBtYXkgbWVhbiBhIGZ1bGwgdXBncmFkZSBvZiBSLCB3aGljaCBpbiB0dXJuCiAgICAjIG1heSBub3QgYmUgd2FycmVudGVkLiAKICAgICN1cGRhdGUuaW5zdGFsbC5wYWNrYWdlcy5hdXRvKGFzayA9IEZBTFNFKSAKICAgIGV2YWwocGFyc2UodGV4dCA9IHNwcmludGYoImluc3RhbGwucGFja2FnZXMoXCIlc1wiLCBkZXBlbmRlbmNpZXMgPSBUUlVFLCByZXBvcyA9IFwiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnL1wiKSIsIHgpKSkKICB9CiAgaWYoaXNUUlVFKHggJWluJSAucGFja2FnZXMoYWxsLmF2YWlsYWJsZSA9IFRSVUUpKSkgeyAKICAgIGV2YWwocGFyc2UodGV4dCA9IHNwcmludGYoInJlcXVpcmUoXCIlc1wiKSIsIHgpKSkKICB9IGVsc2UgewogICAgaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJCaW9jTWFuYWdlciIpKQogICAgICBpbnN0YWxsLnBhY2thZ2VzKCJCaW9jTWFuYWdlciIpCiAgICBCaW9jTWFuYWdlcjo6aW5zdGFsbCgpICMgdGhpcyB3b3VsZCBlbnRhaWwgdXBkYXRpbmcgaW5zdGFsbGVkIHBhY2thZ2VzLCB3aGljaCBpbiB0dXJuZWQgbWF5IG5vdCBiZSB3YXJyZW50ZWQKICAgIAogICAgIyBDb2RlIGZvciBvbGRlciB2ZXJzaW9ucyBvZiBSICg8My41LjApCiAgICAjIHNvdXJjZSgiaHR0cDovL2Jpb2NvbmR1Y3Rvci5vcmcvYmlvY0xpdGUuUiIpCiAgICAjIFVwZGF0ZSBpbnN0YWxsZWQgcGFja2FnZXMgLSB0aGlzIG1heSBtZWFuIGEgZnVsbCB1cGdyYWRlIG9mIFIsIHdoaWNoIGluIHR1cm4KICAgICMgbWF5IG5vdCBiZSB3YXJyZW50ZWQuCiAgICAjIGJpb2NMaXRlKGNoYXJhY3RlcigpLCBhc2sgPSBGQUxTRSkgCiAgICBldmFsKHBhcnNlKHRleHQgPSBzcHJpbnRmKCJCaW9jTWFuYWdlcjo6aW5zdGFsbChcIiVzXCIpIiwgeCkpKQogICAgZXZhbChwYXJzZSh0ZXh0ID0gc3ByaW50ZigicmVxdWlyZShcIiVzXCIpIiwgeCkpKQogIH0KfQpgYGAKCgpfLi4uIGFuZCBsb2FkIHRob3NlIHBhY2thZ2VzLl8KYGBge3IgbG9hZGluZ19wYWNrYWdlcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcy5hdXRvKCJyZWFkciIpCmluc3RhbGwucGFja2FnZXMuYXV0bygib3B0cGFyc2UiKQppbnN0YWxsLnBhY2thZ2VzLmF1dG8oInRvb2xzIikKaW5zdGFsbC5wYWNrYWdlcy5hdXRvKCJkcGx5ciIpCmluc3RhbGwucGFja2FnZXMuYXV0bygidGlkeXIiKQppbnN0YWxsLnBhY2thZ2VzLmF1dG8oIm5hbmlhciIpCgojIFRvIGdldCAnZGF0YS50YWJsZScgd2l0aCAnZndyaXRlJyB0byBiZSBhYmxlIHRvIGRpcmVjdGx5IHdyaXRlIGd6aXBwZWQtZmlsZXMKIyBSZWY6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQyNzg4NDAxL2lzLXBvc3NpYmxlLXRvLXVzZS1md3JpdGUtZnJvbS1kYXRhLXRhYmxlLXdpdGgtZ3pmaWxlCiMgaW5zdGFsbC5wYWNrYWdlcygiZGF0YS50YWJsZSIsIHJlcG9zID0gImh0dHBzOi8vUmRhdGF0YWJsZS5naXRsYWIuaW8vZGF0YS50YWJsZSIpCmxpYnJhcnkoZGF0YS50YWJsZSkKCmluc3RhbGwucGFja2FnZXMuYXV0bygidGlkeXZlcnNlIikKaW5zdGFsbC5wYWNrYWdlcy5hdXRvKCJrbml0ciIpCmluc3RhbGwucGFja2FnZXMuYXV0bygiRFQiKQppbnN0YWxsLnBhY2thZ2VzLmF1dG8oImVlcHRvb2xzIikKCmluc3RhbGwucGFja2FnZXMuYXV0bygiaGF2ZW4iKQppbnN0YWxsLnBhY2thZ2VzLmF1dG8oInRhYmxlb25lIikKCmluc3RhbGwucGFja2FnZXMuYXV0bygiQmxhbmRBbHRtYW5MZWgiKQoKIyBJbnN0YWxsIHRoZSBkZXZ0b29scyBwYWNrYWdlIGZyb20gSGFkbGV5IFdpY2toYW0KaW5zdGFsbC5wYWNrYWdlcy5hdXRvKCdkZXZ0b29scycpCgojIGZvciBwbG90dGluZwppbnN0YWxsLnBhY2thZ2VzLmF1dG8oInBoZWF0bWFwIikKaW5zdGFsbC5wYWNrYWdlcy5hdXRvKCJmb3Jlc3RwbG90IikKaW5zdGFsbC5wYWNrYWdlcy5hdXRvKCJnZ3Bsb3QyIikKCmluc3RhbGwucGFja2FnZXMuYXV0bygiZ2dwdWJyIikKCmluc3RhbGwucGFja2FnZXMuYXV0bygiVXBTZXRSIikKCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigidGhvbWFzcDg1L3BhdGNod29yayIpCgpgYGAKCl9XZSB3aWxsIGNyZWF0ZSBhIGRhdGVzdGFtcCBhbmQgZGVmaW5lIHRoZSBVdHJlY2h0IFNjaWVuY2UgUGFyayBDb2xvdXIgU2NoZW1lXy4KYGBge3IgU2V0dGluZzogQ29sb3JzfQoKVG9kYXkgPSBmb3JtYXQoYXMuRGF0ZShhcy5QT1NJWGx0KFN5cy50aW1lKCkpKSwgIiVZJW0lZCIpClRvZGF5LlJlcG9ydCA9IGZvcm1hdChhcy5EYXRlKGFzLlBPU0lYbHQoU3lzLnRpbWUoKSkpLCAiJUEsICVCICVkLCAlWSIpCgojIyMgVXRyZWNodFNjaWVuY2VQYXJrQ29sb3Vyc1NjaGVtZQojIyMKIyMjIFdlYnNpdGV0b2NvbnZlcnRIRVh0b1JHQjpodHRwOi8vaGV4LmNvbG9ycnJzLmNvbS4KIyMjIEZvcnNvbWVmdW5jdGlvbnN5b3VzaG91bGRkaXZpZGV0aGVzZW51bWJlcnNieTI1NS4KIyMjCiMjIwlOby4JQ29sb3IJCQkgICAgICBIRVgJKFJHQikJCQkJCQkgICAgICAgICAgICAgIENIUgkJICBNQUYvSU5GTwojIyMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjCTEJICB5ZWxsb3cJCQkgICAgI0ZCQjgyMCAoMjUxLDE4NCwzMikJCQkJICAgICAgPT4JMQkJb3IgMS4wPklORk8KIyMjCTIJICBnb2xkCQkJICAgICAgI0Y1OUQxMCAoMjQ1LDE1NywxNikJCQkJICAgICAgPT4JMgkJCiMjIwkzCSAgc2FsbW9uCQkJICAgICNFNTU3MzggKDIyOSw4Nyw1NikJCQkJICAgICAgPT4JMwkJb3IgMC4wNTxNQUY8MC4yIG9yIDAuNDxJTkZPPDAuNgojIyMJNAkgIGRhcmtwaW5rCQkgICAgI0RCMDAzRiAoKDIxOSwwLDYzKQkJCQkgICAgICA9Pgk0CQkKIyMjCTUJICBsaWdodHBpbmsJCSAgICAjRTM1NDkzICgyMjcsODQsMTQ3KQkJCQkgICAgICA9Pgk1CQlvciAwLjg8SU5GTzwxLjAKIyMjCTYJICBwaW5rCQkJICAgICAgI0Q1MjY3QiAoMjEzLDM4LDEyMykJCQkJICAgICAgPT4JNgkJCiMjIwk3CSAgaGFyZHBpbmsJCSAgICAjQ0MwMDcxICgyMDQsMCwxMTMpCQkJCSAgICAgID0+CTcJCQojIyMJOAkgIGxpZ2h0cHVycGxlCSAgICAjQTg0NDhBICgxNjgsNjgsMTM4KQkJCQkgICAgICA9Pgk4CQkKIyMjCTkJICBwdXJwbGUJCQkgICAgIzlBMzQ4MCAoMTU0LDUyLDEyOCkJCQkJICAgICAgPT4JOQkJCiMjIwkxMAlsYXZlbmRlbAkJICAgICM4RDVCOUEgKDE0MSw5MSwxNTQpCQkJCSAgICAgID0+CTEwCQkKIyMjCTExCWJsdWVwdXJwbGUJCSAgIzcwNTI5NiAoMTEyLDgyLDE1MCkJCQkJICAgICAgPT4JMTEJCQojIyMJMTIJcHVycGxlYmx1ZQkJICAjNjg2QUE5ICgxMDQsMTA2LDE2OSkJCQkgICAgICA9PgkxMgkJCiMjIwkxMwlsaWdodHB1cnBsZWJsdWUJIzYxNzNBRCAoOTcsMTE1LDE3My8xMDEsMTIwLDE4MCkJPT4JMTMJCQojIyMJMTQJc2VhYmx1ZQkJCSAgICAjNEM4MUJGICg3NiwxMjksMTkxKQkJCQkgICAgICA9PgkxNAkJCiMjIwkxNQlza3libHVlCQkJICAgICMyRjhCQzkgKDQ3LDEzOSwyMDEpCQkJCSAgICAgID0+CTE1CQkKIyMjCTE2CWF6dXJibHVlCQkgICAgIzEyOTBEOSAoMTgsMTQ0LDIxNykJCQkJICAgICAgPT4JMTYJCW9yIDAuMDE8TUFGPDAuMDUgb3IgMC4yPElORk88MC40CiMjIwkxNwlsaWdodGF6dXJibHVlCSAgIzEzOTZEOCAoMTksMTUwLDIxNikJCQkJICAgICAgPT4JMTcJCQojIyMJMTgJZ3JlZW5ibHVlCQkgICAgIzE1QTZDMSAoMjEsMTY2LDE5MykJCQkJICAgICAgPT4JMTgJCQojIyMJMTkJc2Vhd2VlZGdyZWVuCSAgIzVFQjE3RiAoOTQsMTc3LDEyNykJCQkJICAgICAgPT4JMTkJCQojIyMJMjAJeWVsbG93Z3JlZW4JCSAgIzg2QjgzMyAoMTM0LDE4NCw1MSkJCQkJICAgICAgPT4JMjAJCQojIyMJMjEJbGlnaHRtb3NzZ3JlZW4JI0M1RDIyMCAoMTk3LDIxMCwzMikJCQkJICAgICAgPT4JMjEJCQojIyMJMjIJbW9zc2dyZWVuCQkgICAgIzlGQzIyOCAoMTU5LDE5NCw0MCkJCQkJICAgICAgPT4JMjIJCW9yIE1BRj4wLjIwIG9yIDAuNjxJTkZPPDAuOAojIyMJMjMJbGlnaHRncmVlbgkgIAkjNzhCMTEzICgxMjAsMTc3LDE5KQkJCQkgICAgICA9PgkyMy9YCiMjIwkyNAlncmVlbgkJCSAgICAgICM0OUEwMUQgKDczLDE2MCwyOSkJCQkJICAgICAgPT4JMjQvWQojIyMJMjUJZ3JleQkJCSAgICAgICM1OTVBNUMgKDg5LDkwLDkyKQkJCQkgICAgICAgID0+CTI1L1hZCW9yIE1BRjwwLjAxIG9yIDAuMDxJTkZPPDAuMgojIyMJMjYJbGlnaHRncmV5CQkgICAgI0EyQTNBNAkoMTYyLDE2MywxNjQpCQkJICAgICAgPT4JMjYvTVQKIyMjCiMjIwlBRERJVElPTkFMIENPTE9SUwojIyMJMjcJbWlkZ3JleQkJCSNEN0Q4RDcKIyMjCTI4CXZlcnlsaWdodGdyZXkJI0VDRUNFQyIKIyMjCTI5CXdoaXRlCQkJI0ZGRkZGRgojIyMJMzAJYmxhY2sJCQkjMDAwMDAwCiMjIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnVpdGhvZl9jb2xvciA9IGMoIiNGQkI4MjAiLCIjRjU5RDEwIiwiI0U1NTczOCIsIiNEQjAwM0YiLCIjRTM1NDkzIiwiI0Q1MjY3QiIsCiAgICAgICAgICAgICAgICAgIiNDQzAwNzEiLCIjQTg0NDhBIiwiIzlBMzQ4MCIsIiM4RDVCOUEiLCIjNzA1Mjk2IiwiIzY4NkFBOSIsCiAgICAgICAgICAgICAgICAgIiM2MTczQUQiLCIjNEM4MUJGIiwiIzJGOEJDOSIsIiMxMjkwRDkiLCIjMTM5NkQ4IiwiIzE1QTZDMSIsCiAgICAgICAgICAgICAgICAgIiM1RUIxN0YiLCIjODZCODMzIiwiI0M1RDIyMCIsIiM5RkMyMjgiLCIjNzhCMTEzIiwiIzQ5QTAxRCIsCiAgICAgICAgICAgICAgICAgIiM1OTVBNUMiLCIjQTJBM0E0IiwgIiNEN0Q4RDciLCAiI0VDRUNFQyIsICIjRkZGRkZGIiwgIiMwMDAwMDAiKQoKdWl0aG9mX2NvbG9yX2xlZ2VuZCA9IGMoIiNGQkI4MjAiLCAiI0Y1OUQxMCIsICIjRTU1NzM4IiwgIiNEQjAwM0YiLCAiI0UzNTQ5MyIsCiAgICAgICAgICAgICAgICAgICAgICAgICIjRDUyNjdCIiwgIiNDQzAwNzEiLCAiI0E4NDQ4QSIsICIjOUEzNDgwIiwgIiM4RDVCOUEiLAogICAgICAgICAgICAgICAgICAgICAgICAiIzcwNTI5NiIsICIjNjg2QUE5IiwgIiM2MTczQUQiLCAiIzRDODFCRiIsICIjMkY4QkM5IiwKICAgICAgICAgICAgICAgICAgICAgICAgIiMxMjkwRDkiLCAiIzEzOTZEOCIsICIjMTVBNkMxIiwgIiM1RUIxN0YiLCAiIzg2QjgzMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICIjQzVEMjIwIiwgIiM5RkMyMjgiLCAiIzc4QjExMyIsICIjNDlBMDFEIiwgIiM1OTVBNUMiLAogICAgICAgICAgICAgICAgICAgICAgICAiI0EyQTNBNCIsICIjRDdEOEQ3IiwgIiNFQ0VDRUMiLCAiI0ZGRkZGRiIsICIjMDAwMDAwIikKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBgCgojIEludHJvZHVjdGlvbgoKIyMgUHJvamVjdCBkZXRhaWxzCgoqQ29sbGFib3JhdG9ycyoKCk1hcnlhbSBLYXZvdXNpLApQYXRyaWNpYSBQZXlzZXIsCk1heGltZSBCb3MsCkNsaW50IE1pbGxlcgoKKlByb2plY3QgSUQqIApBRV8yMDIwMDUxMl9DT0xfTUtBVk9VU0lfTUJPU19DSEFSR0VfMTAwMEdfQ0FDCgoKIyMgQmFja2dyb3VuZAoKSGVyZSB3ZSBtYXAgdGhlIENIQVJHRSBDb25zb3J0aXVtIDEwMDBHIEdXQVMgb24gX2Nvcm9uYXJ5IGFydGVyeSBjYWxjaWZpY2F0aW9uIChDQUMpXyBzdXNjZXB0aWJpbGl0eSBsb2NpIHRvIHRoZSBzaW5nbGUtY2VsbCBjYXJvdGlkIHBsYXF1ZSBkYXRhLiBUaGVzZSBhcmUgZ2l2ZW4gaW46CgotIGBWYXJpYW50cy54bHN4IC0gc2hlZXQgVmFyaWFudHNgLCBvcmlnaW5hbGx5IGZyb20gYEluZFNpZ1NOUHNmb3JTYW5kZXIueGxzeGAKLSBgR2VuZXMueGxzeGAsIG9yaWdpbmFsbHkgZnJvbSBgMjAyMTAxMjdfT3ZlcnZpZXdfR2VuZXNfTU1Cb3NfU2FuZGVyLnhsc3hgCi0gYFZhcmlhbnRzLnhsc3ggLSBzaGVldCBDcmVkaWJsZVNldGAsIG9yaWdpbmFsbHkgZnJvbSBgMjAyMTAxMjdfT3ZlcnZpZXdfR2VuZXNfTU1Cb3NfU2FuZGVyLnhsc3hgCgpgYGB7ciBDQUMgdGFyZ2V0c30KbGlicmFyeShvcGVueGxzeCkKCiMgb2xkIGxpc3QKIyBnZW5lX2xpc3QgPC0gcmVhZC54bHN4KHBhc3RlMChUQVJHRVRfbG9jLCAiL0dlbmVMaXN0XzE1MDQyMDIwLnhsc3giKSkKCiMgdXBkYXRlIGxpc3QKZ2VuZV9saXN0IDwtIHJlYWQueGxzeChwYXN0ZTAoU05QX2xvYywgIi9HZW5lcy54bHN4IikpCgp2YXJpYW50X2xpc3QgPC0gcmVhZC54bHN4KHBhc3RlMChTTlBfbG9jLCAiL1ZhcmlhbnRzLnhsc3giKSwgc2hlZXQgPSAiVmFyaWFudHMiKQpjcmVkc2V0X2xpc3QgPC0gcmVhZC54bHN4KHBhc3RlMChTTlBfbG9jLCAiL1ZhcmlhbnRzLnhsc3giKSwgc2hlZXQgPSAiQ3JlZGlibGVTZXQiKQoKRFQ6OmRhdGF0YWJsZShnZW5lX2xpc3QpCgpEVDo6ZGF0YXRhYmxlKHZhcmlhbnRfbGlzdCkKRFQ6OmRhdGF0YWJsZShjcmVkc2V0X2xpc3QpCgpgYGAKCldlIHdpbGwgY29uc3RydWN0IGEgbGlzdCBvZiBnZW5lcyB0byBtYXAgdG8gb3VyIHNjUk5Bc2VxIGRhdGEuIAoKYGBge3IgQ0FDIHRhcmdldHMgZm9yIG1hcHBpbmd9Cgp0YXJnZXRfZ2VuZXMgPC0gdW5saXN0KGdlbmVfbGlzdCRzeW1ib2wpCnRhcmdldF9nZW5lcwpgYGAKCgoKV2Ugd2lsbCB0ZXN0IHRoZSBoeXBvdGhlc2lzIHRoYXQgQ0FDIHN1c2NlcHRpYmlsaXR5IGxvY2kgYXJlIGFzc29jaWF0ZWQgd2l0aCBwbGFxdWUgY2hhcmFjdGVyaXN0aWNzLiBXZSB3aWxsIHVzZSBkYXRhIGZyb20gdGhlIEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkuCgojIyBTdHVkeSBkZXNpZ24KCldlIHdpbGwgcGVyZm9ybSByZWdyZXNzaW9uIGFuYWx5c2VzIGFkanVzdGVkIGZvciBhZ2UsIHNleCAod2hlcmUgYXBwbGljYWJsZSkgYW5kIHByaW5jaXBhbCBjb21wb25lbnRzLgoKIyMgTW9kZWxpbmcKCldlIHdpbGwgYXBwbHkgdGhlIGZvbGxvd2luZyBtb2RlbHM6Cgptb2RlbCAxOiBgcGhlbm90eXBlIH4gYWdlICsgc2V4ICsgY2hpcC11c2VkICsgUEMxICsgUEMyICsgeWVhci1vZi1zdXJnZXJ5YAoKcGhlbm90eXBlcyBhcmU6CgotIGBjYWxjaWZpY2F0aW9uYCwgY29kZWQgYENhbGMuYmluYCBuby9taW5vciB2cy4gbW9kZXJhdGUvaGVhdnkgc3RhaW5pbmcKLSBgY29sbGFnZW5gLCBjb2RlZCBgQ29sbGFnZW4uYmluYCBuby9taW5vciB2cy4gbW9kZXJhdGUvaGVhdnkgc3RhaW5pbmcKLSBgZmF0MTBgLCBjb2RlZCBgRmF0LmJpbl8xMGAgbm8vPDEwJSBmYXQgdnMuID4xMCUgZmF0Ci0gYGZhdDQwYCwgY29kZWQgYEZhdC5iaW5fNDBgIG5vLzw0MCUgZmF0IHZzLiA+NDAlIGZhdAotIGBpbnRyYXBsYXF1ZSBoZW1vcnJoYWdlYCwgY29kZWQgYElQSC5iaW5gIG5vIHZzLiB5ZXMKLSBgbWFjcm9waGFnZXMgKENENjgpYCwgY29kZWQgYG1hY21lYW4wYCBtZWFuIG9mIGNvbXB1dGVyLWFzc2lzdGVkIGNhbGN1bGF0aW9uIENENjg8c3VwPis8L3N1cD4gcmVnaW9uIG9mIGludGVyZXN0Ci0gYHNtb290aCBtdXNjbGUgY2VsbHMgKGFscGhhLWFjdGluKWAsIGNvZGVkIGBzbWNtZWFuMGAgbWVhbiBvZiBjb21wdXRlci1hc3Npc3RlZCBjYWxjdWxhdGlvbiBTTUE8c3VwPis8L3N1cD4gcmVnaW9uIG9mIGludGVyZXN0Ci0gYGludHJhcGxhcXVlIHZlc3NlbCBkZW5zaXR5IChDRDM0KWAsIGNvZGVkIGB2ZXNzZWxfZGVuc2l0eWAgbWFudWFsbHkgY291bnRlZCBDRDM0PHN1cD4rPC9zdXA+IGNlbGxzIHBlciAzLTQgaG90c3BvdHMKLSBgbWFzdCBjZWxsc2AsIGNvZGVkIGBNYXN0X2NlbGxzX3BsYXF1ZWAgbWFudWFsbHkgY291bnRlZCBtYXN0IGNlbGwgdHJ5cHRhc2U8c3VwPis8L3N1cD4gY2VsbHMgKGh0dHBzOi8vYWNhZGVtaWMub3VwLmNvbS9ldXJoZWFydGovYXJ0aWNsZS8zNC80OC8zNjk5LzQ4NDk4MSkKLSBgbmV1dHJvcGhpbHMgKENENjZiKWAsIGNvZGVkIGBuZXV0cm9waGlsc2AgbWFudWFsbHkgY291bnRlZCBDRDY2YjxzdXA+Kzwvc3VwPiBjZWxscyAoaHR0cHM6Ly9wdWJtZWQubmNiaS5ubG0ubmloLmdvdi8yMDU5NTY1MC8pCgoKIyMgQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeQoKVGhlICpbQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeSAoQUUpXShodHRwOi8vd3d3LmF0aGVyb2V4cHJlc3Mubmwpe3RhcmdldD0iX2JsYW5rIn0qIGNvbnRhaW5zIHBsYXF1ZSBtYXRlcmlhbCBvZiBwYXRpZW50cyB0aGF0IHVuZGVyd2VudCBlbmRhcnRlcmVjdG9teWF0IHR3byBEdXRjaCB0ZXJ0aWFyeSByZWZlcnJhbCBjZW50ZXJzLiBEZXRhaWxzIG9mIHRoZSBzdHVkeSBkZXNpZ24gd2VyZSBkZXNjcmliZWQgYmVmb3JlLiBCcmllZmx5LCBibG9vZCBhbmQgcGxhcXVlIG1hdGVyaWFsIHdlcmUgb2J0YWluZWQgZHVyaW5nIGVuZGFydGVyZWN0b215IGFuZCBzdG9yZWQgYXQgLTgwIOKEgy4gT25seSBjYXJvdGlkIGVuZGFydGVyZWN0b215IChDRUEpIHBhdGllbnRzIHdlcmUgaW5jbHVkZWQgaW4gdGhlIHByZXNlbnQgc3R1ZHkuIEFsbCBwYXRpZW50cyBwcm92aWRlZCBpbmZvcm1lZCBjb25zZW50IGFuZCB0aGUgc3R1ZHkgd2FzIGFwcHJvdmVkIGJ5IHRoZSBtZWRpY2FsIGV0aGljcyBjb21taXR0ZWUuCgojIyBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeQoKIyMjIEROQSBpc29sYXRpb24gYW5kIGdlbm90eXBpbmcKCldlIGdlbm90eXBlZCB0aGUgQUUgaW4gdGhyZWUgc2VwYXJhdGUsIGJ1dCBjb25zZWN1dGl2ZSBleHBlcmltZW50cy4gSW4gc2hvcnQsIEROQSB3YXMgZXh0cmFjdGVkIGZyb20gRURUQSBibG9vZCBvciAod2hlbiBubyBibG9vZCB3YXMgYXZhaWxhYmxlKSBwbGFxdWUgc2FtcGxlcyBvZiAxLDg1OCBjb25zZWN1dGl2ZSBwYXRpZW50cyBmcm9tIHRoZSBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IGFuZCBnZW5vdHlwZWQgaW4gMyBiYXRjaGVzLiAKCkZvciB0aGUgX0F0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5IDEgKEFFR1MxKV8gODkxIHBhdGllbnRzICg2MDIgbWFsZXMsIDI2MiBmZW1hbGVzLCAyNyB1bmtub3duIHNleCksIGluY2x1ZGVkIGJldHdlZW4gMjAwMiBhbmQgMjAwNywgd2VyZSBnZW5vdHlwZWQgKDQ0MCw3NjMgbWFya2VycykgdXNpbmcgdGhlIEFmZnltZXRyaXggR2Vub21lLVdpZGUgSHVtYW4gU05QIEFycmF5IDUuMCAoU05QNSkgY2hpcCAoQWZmeW1ldHJpeCBJbmMuLCBTYW50YSBDbGFyYSwgQ0EsIFVTQSkgYXQgW0V1cm9maW5zIEdlbm9taWNzXShodHRwczovL3d3dy5ldXJvZmluc2dlbm9taWNzLmV1Lyl7dGFyZ2V0PSJfYmxhbmsifSAoZm9ybWVybHkga25vd24gYXMgQVJPUykuIAoKRm9yIHRoZSBfQXRoZXJvLUV4cHJlc3MgR2Vub21pY3MgU3R1ZHkgMiAoQUVHUzIpXyA5NTQgcGF0aWVudHMgKDY0MCBtYWtlcywgMzEzIGZlbWFsZXMsIDEgdW5rbm93biBzZXgpLCBpbmNsdWRlZCBiZXR3ZWVuIDIwMDIgYW5kIDIwMTMsIHdlcmUgZ2Vub3R5cGVkICg1ODcsMzUxIG1hcmtlcnMpIHVzaW5nIHRoZSBBZmZ5bWV0cml4IEF4aW9t4pOHIEdXIENFVSAxIEFycmF5IChBeE0pIGF0IHRoZSBbR2Vub21lIEFuYWx5c2lzIENlbnRlcl0oaHR0cHM6Ly93d3cuaGVsbWhvbHR6LW11ZW5jaGVuLmRlL25vX2NhY2hlL2dhYy9pbmRleC5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9LgoKRm9yIHRoZSBfQXRoZXJvLUV4cHJlc3MgR2Vub21pY3MgU3R1ZHkgMyAoQUVHUzMpXyA2NTggcGF0aWVudHMgKDQ0OCBtYWxlcywgMjAzIGZlbWFsZXMsIDUgdW5rbm93biBzZXgpLCBpbmNsdWRlZCBiZXR3ZWVuIDIwMDIgYW5kIDIwMTYsIHdlcmUgZ2Vub3R5cGVkICg2OTMsOTMxIG1hcmtlcnMpIHVzaW5nIHRoZSBJbGx1bWluYSBHU0EgTUQgdjEgQmVhZEFycmF5IChHU0EpIGF0IFtIdW1hbiBHZW5vbWljcyBGYWNpbGl0eSwgSFVHRS1GXShodHRwOi8vZ2xpbWRuYS5vcmcvaW5kZXguaHRtbCl7dGFyZ2V0PSJfYmxhbmsifS4gCgpBbGwgZXhwZXJpbWVudHMgd2VyZSBjYXJyaWVkIG91dCBhY2NvcmRpbmcgdG8gT0VDRCBzdGFuZGFyZHMuIAoKIyMjIEdlbm90eXBpbmcgY2FsbGluZwoKV2UgdXNlZCB0aGUgZ2Vub3R5cGluZyBjYWxsaW5nIGFsZ29yaXRobXMgYXMgYWR2aXNlZCBieSBBZmZ5bWV0cml4IChBRUdTMSBhbmQgQUVHUzIpIGFuZCBJbGx1bWluYSAoQUVHUzMpOgoKLSBBRUdTMTogQlJMTU0tUAotIEFFR1MyOiBBeGlvbUdUMQotIEFFR1MzOiBJbGx1bWluYSBHZW5vbWVTdHVkaW8KCiMjIyBRdWFsaXR5IGNvbnRyb2wgYWZ0ZXIgZ2Vub3R5cGluZwoKQWZ0ZXIgZ2Vub3R5cGUgY2FsbGluZywgd2UgYWRoZXJlZCB0byBjb21tdW5pdHkgc3RhbmRhcmQgcXVhbGl0eSBjb250cm9sIGFuZCBhc3N1cmFuY2UgKFFDQSkgcHJvY2VkdXJlcyBvZiB0aGUgZ2Vub3R5cGUgZGF0YSBmcm9tIEFFR1MxLCBBRUdTMiwgYW5kIEFFR1MzLiBTYW1wbGVzIHdpdGggbG93IGF2ZXJhZ2UgZ2Vub3R5cGUgY2FsbGluZyBhbmQgc2V4IGRpc2NyZXBhbmNpZXMgKGNvbXBhcmVkIHRvIHRoZSBjbGluaWNhbCBkYXRhIGF2YWlsYWJsZSkgd2VyZSBleGNsdWRlZC4gVGhlIGRhdGEgd2FzIGZ1cnRoZXIgZmlsdGVyZWQgb246CgoxKSBpbmRpdmlkdWFsIChzYW1wbGUpIGNhbGwgcmF0ZSA+IDk3JSwgCjIpIFNOUCBjYWxsIHJhdGUgPiA5NyUsIAozKSBtaW5vciBhbGxlbGUgZnJlcXVlbmNpZXMgKE1BRikgPiAzJSwgCjQpIGF2ZXJhZ2UgaGV0ZXJvenlnb3NpdHkgcmF0ZSDCsSAzLjAgcy5kLiwgCjUpIHJlbGF0ZWRuZXNzIChwaS1oYXQgPiAwLjIwKSwgCjYpIEhhcmR54oCTV2VpbmJlcmcgRXF1aWxpYnJpdW0gKEhXRSBwIDwgMS4ww5cxMDxzdXA+4oiSMzxcc3VwPiksIGFuZAo3KSBNb25vbW9ycGhpYyBTTlBzICg8IDEuMMOXMTA8c3VwPuKIkjY8XHN1cD4pLiAKCkFmdGVyIFFDQSAyLDQ5MyBzYW1wbGVzIHJlbWFpbmVkLCAxMDggb2Ygbm9uLUV1cm9wZWFuIGRlc2NlbnQvYW5jZXN0cnksIGFuZCAxNTYgcmVsYXRlZCBwYWlycy4gIFRoZXNlIGNvbXByaXNlIDg5MCBzYW1wbGVzIGFuZCA0MDcsNzEyIFNOUHMgaW4gQUVHUzEsIDg2OSBzYW1wbGVzIGFuZCA1MzQsNTA4IFNOUHMgaW4gQUVHUzIsIGFuZCA2NDk5NTQgc2FtcGxlcyBhbmQgNTM0LDUwOCBTTlBzIGluIEFFR1MzIHJlbWFpbmVkLgoKIyMjIEltcHV0YXRpb24KCkJlZm9yZSBwaGFzaW5nIHVzaW5nIFNIQVBFSVQyLCBkYXRhIHdhcyBsaWZ0ZWQgdG8gZ2Vub21lIGJ1aWxkIGIzNyB1c2luZyB0aGUgbGlmdE92ZXIgdG9vbCBmcm9tIFVDU0MgKGh0dHBzOi8vZ2Vub21lLnVjc2MuZWR1L2NnaS1iaW4vaGdMaWZ0T3ZlcikuIEZpbmFsbHksIGRhdGEgd2FzIGltcHV0ZWQgd2l0aCAxMDAwRyBwaGFzZSAzLCB2ZXJzaW9uIDUgYW5kIEhSQyByZWxlYXNlIDEuMSBhcyBhIHJlZmVyZW5jZSB1c2luZyB0aGUgW01pY2hpZ2FuIEltcHV0YXRpb24gU2VydmVyXShodHRwczovL2ltcHV0YXRpb25zZXJ2ZXIuc3BoLnVtaWNoLmVkdS8pe3RhcmdldD0iX2JsYW5rIn0uIFRoZXNlIHJlc3VsdHMgd2VyZSBmdXJ0aGVyIGludGVncmF0ZWQgdXNpbmcgUUNUT09MIHYyLCB3aGVyZSBIUkMgaW1wdXRlZCB2YXJpYW50cyBhcmUgZ2l2ZW4gcHJlY2VuZGVuY2Ugb3ZlciAxMDAwRyBwaGFzZSAzIGltcHV0ZWQgdmFyaWFudHMuIAoKIyMjIFF1YWxpdHkgY29udHJvbCBhZnRlciBpbXB1dGF0aW9uCgpXZSBjb21wYXJlZCBxdWFsaXR5IG9mIHRoZSB0aHJlZSBBRUdTIGRhdGFzZXRzLCBhbmQgbGlzdGVkIHNvbWUgdmFyaWFibGVzIG9mIGludGVyZXN0LgoKLSBzYW1wbGUgdHlwZSAoRURUQSBibG9vZCBvciBwbGFxdWUpCi0gZ2Vub3R5cGluZyBjaGlwIHVzZWQKLSByZWFzb24gZm9yIGZpbHRlcmluZwoKV2UgY2hlY2tlZCB0aGUgc3R1ZHl0eXBlIChBRSBvciBub3QpLCBhbmQgX2lkZW50aXR5LWJ5LWRlc2NlbnQgKElCRClfIHdpdGhpbiBhbmQgYmV0d2VlbiBkYXRhc2V0cyB0byBhaWQgaW4gc2FtcGxlIG1peHVwcywgZHVwbGljYXRlIHNhbXBsZSB1c2UsIGFuZCByZWxhdGVkbmVzcy4gSW4gYWRkaXRpb24sIGR1cmluZyBnZW5vdHlwaW5nIHF1YWxpdHkgY29udHJvbCBzYW1wbGVzIHdlcmUgaWRlbnRpZmllZCB0aGF0IGRldmlhdGVkIGZyb20gX0hhcmR5LVdlaW5iZXJnIEVxdWlsaWJyaXVtIChIV0UpXywgaGFkIGRpc2NvcmRhbmNlIGluIHNleC1jb2RpbmcgYW5kIGdlbm90eXBlIHNleCwgYW5kIGRldmlhdGVkIGZyb20gdGhlIF9wcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIChQQ0EpXyBwbG90LgoKV2Ugd2lsbCBsb2FkIHRoZSBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IGRhdGEsIGFuZCBhbGwgdGhlIHNhbXBsZXMgdGhhdCB3ZXJlIHNlbmQgZm9yIGdlbm90eXBpbmcgYW5kIHRoZSBmaW5hbCBRQydlZCBzYW1wbGVMaXN0LgoKIyMgTG9hZGluZyBkYXRhCgpMb2FkaW5nIEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkgY2xpbmljYWwgYW5kIGJpb2JhbmsgZGF0YSwgYXMgd2VsbCBhcyB0aGUgU2FtcGxlTGlzdCBvZiBnZW5ldGljIGRhdGEuCmBgYHtyIExvYWRBRURCfQpjYXQoIiogZ2V0IEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkgRGF0YWJhc2UuLi4iKQojIE1FVEhPRCAxOiBJdCBzZWVtcyB0aGlzIG1ldGhvZCBnaXZlcyBsb2FkcyBvZiBlcnJvcnMgYW5kIHdhcm5pbmdzLCB3aGljaCBhbGwgYXJlIGhhcmQgdG8gY29tcHJlaGVuZAojICAgICAgICAgICBvciBkZWJ1Zy4gV2UgZXhwZWN0IDMsNTI3IHNhbXBsZXMsIGFuZCA5MjcgdmFyaWFibGVzOyB3ZSBnZXQgOTI3IHZhcmlhYmxlcyEhIQojIEFFZGF0YSA9IGFzLmRhdGEudGFibGUocmVhZC5zcHNzKHBhc3RlMChJTlBfbG9jLCIvMjAxNy0xTkVXX0F0aGVyb0V4cHJlc3NEYXRhYmFzZV9TY2llbnRpZmljQUVfMjAxNzEzMDZfdjEuMC5zYXYiKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmltLmZhY3Rvci5uYW1lcyA9IFRSVUUsIHRyaW1fdmFsdWVzID0gVFJVRSwgIyB3ZSB0cmltIHNwYWNlcyBpbiB2YWx1ZXMKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWVuY29kZSA9IFRSVUUsICMgd2UgcmUtZW5jb2RlIHRvIHRoZSBsb2NhbCBsb2NhbGUgZW5jb2RpbmcKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQudW5kZWNsYXJlZC5sZXZlbHMgPSAiYXBwZW5kIiwgIyB3ZSBkbyAqbm90KiB3YW50IHRvIGNvbnZlcnQgdG8gUi1mYWN0b3JzCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLnZhbHVlLmxhYmVscyA9IEZBTFNFLCAjIHdlIGRvICpub3QqIGNvbnZlcnQgdmFyaWFibGVzIHdpdGggdmFsdWUgbGFiZWxzIGludG8gUiBmYWN0b3JzCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLm1pc3NpbmdzID0gVFJVRSwgc3ViID0gIk5BIiwgIyB3ZSB3aWxsIHNldCBldmVyeSBtaXNzaW5nIHZhcmlhYmxlIHRvIE5BCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVwbGljYXRlZC52YWx1ZS5sYWJlbHMgPSAiY29uZGVuc2UiLCAjIHdlIHdpbGwgY29uZGVuc2UgZHVwbGljYXRlZCB2YWx1ZSBsYWJlbHMKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0by5kYXRhLmZyYW1lID0gVFJVRSkpCiMgQUVkYXRhLmxhYmVscyA8LSBhcy5kYXRhLnRhYmxlKGF0dHIoQUVkYXRhLCAidmFyaWFibGUubGFiZWxzIikpCiMgbmFtZXMoQUVkYXRhLmxhYmVscykgPC0gIlZhcmlhYmxlIgoKIyBNRVRIT0QgMjogVXNpbmcgbGlicmFyeSgiaGF2ZW4iKSBpbXBvcnRpbmcgc2VlbXMgZmxhd2xlc3M7IGJlc3QgYXJndW1lbnQgYmVpbmc6CiMgICAgICAgICAgIHdlIGV4cGVjdCAzLDUyNyBzYW1wbGVzIGFuZCA4ODggdmFyaWFibGVzLCB3aGljaCBpcyB3aGF0IHlvdSdkIGdldCB3aXRoIHRoaXMgbWV0aG9kCiMgICAgICAgICAgIFNvIGZvciBub3csIE1FVEhPRCAyIGlzIHByZWZlcmVkLiAKIyAgICAgICAgICAgIApyZXF1aXJlKGhhdmVuKQoKIyBBRURCIDwtIGhhdmVuOjpyZWFkX3NhdihwYXN0ZTAoQUVEQl9sb2MsICIvMjAxOS0zTkVXX0F0aGVyb0V4cHJlc3NEYXRhYmFzZV9TY2llbnRpZmljQUVfMDIwNzIwMTlfSUNfYWRkZWQuc2F2IikpCkFFREIgPC0gaGF2ZW46OnJlYWRfc2F2KHBhc3RlMChBRURCX2xvYywgIi8yMDIwXzFfTkVXX0F0aGVyb0V4cHJlc3NEYXRhYmFzZV9TY2llbnRpZmljQUVfMTYtMDMtMjAyMC5zYXYiKSkKCiMgd3JpdGluZyBvZmYgdGhlIFNQU1MgZGF0YSB0byBhbiBFeGNlbC4KIyBmd3JpdGUoQUVkYXRhLCBmaWxlID0gcGFzdGUwKElOUF9sb2MsIi8yMDE3LTFORVdfQXRoZXJvRXhwcmVzc0RhdGFiYXNlX1NjaWVudGlmaWNBRV8yMDE3MTMwNl92MS4wLnZhbHVlcy54bHN4IiksIAojICAgICAgICBzZXAgPSAiOyIsIG5hID0gIk5BIiwgZGVjID0gIi4iLCBjb2wubmFtZXMgPSBUUlVFLCByb3cubmFtZXMgPSBGQUxTRSwKIyAgICAgICAgZGF0ZVRpbWVBcyA9ICJJU08iLCBzaG93UHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSkKIyB3YXJuaW5ncygpCgpBRURCWzE6MTAsIDE6MTBdCmRpbShBRURCKQoKY2F0KCIqIGdldCBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeSBrZXlzLi4uIikKQUVHUzEyMy5zYW1wbGVMaXN0LmtleXRhYmxlIDwtIGZyZWFkKHBhc3RlMChBRUdTUUNfbG9jLCAiL1FDL1NFTEVDVElPTlMvMjAyMDAzMTkuUUMuQUVHUzEyMy5zYW1wbGVMaXN0LmtleXRhYmxlLnR4dCIpKQoKZGltKEFFR1MxMjMuc2FtcGxlTGlzdC5rZXl0YWJsZSkKIyBBRUdTMTIzLnNhbXBsZUxpc3Qua2V5dGFibGVbMToxMCwgMToxMF0KCgpgYGAKCiMjIyMgRXhhbWluZSBBRURCCgpXZSBjYW4gZXhhbWluZSB0aGUgY29udGVudHMgb2YgdGhlIEF0aGVyby1FeHByZXNzIEJpb2JhbmsgZGF0YXNldCB0byBrbm93IHdoYXQgZWFjaCB2YXJpYWJsZSBpcyBjYWxsZWQsIHdoYXQgY2xhc3MgKHR5cGUpIGl0IGhhcywgYW5kIHdoYXQgdGhlIHZhcmlhYmxlIGRlc2NyaXB0aW9uIGlzLiAKClRoZXJlIGlzIGFuIGV4Y2VsbGVudCBwb3N0IG9uIHRoaXM6IGh0dHBzOi8vd3d3LnItYmxvZ2dlcnMuY29tL3dvcmtpbmctd2l0aC1zcHNzLWxhYmVscy1pbi1yLy4gCmBgYHtyIEFFREI6IGRlc2NyaWJlfQpBRURCICU+JSBzalBsb3Q6OnZpZXdfZGYoc2hvdy50eXBlID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cuZnJxID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cucHJjID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cubmEgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgIG1heC5sZW4gPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHdyYXAubGFiZWxzID0gMjAsCiAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgdXNlLnZpZXdlciA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFREIuZGljdGlvbmFyeS5odG1sIikpIApgYGAKCgojIyMgRml4IGNsaW5pY2FsIGRhdGEKCldlIG5lZWQgdG8gYmUgdmVyeSBzdHJpY3QgaW4gZGVmaW5pbmcgX3N5bXB0b21zLl8gVGhlcmVmb3JlIHdlIHdpbGwgZml4IGEgbmV3IHZhcmlhYmxlIHRoYXQgZ3JvdXBzIF9zeW1wdG9tc18gYXQgaW5jbHVzaW9uLgoKQ29kaW5nIG9mIF9zeW1wdG9tc18gaXMgYXMgZm9sbG93czoKCi0gbWlzc2luZwktOTk5CQotIEFzeW1wdG9tYXRpYwkwCQotIFRJQQkxCQotIG1pbm9yIHN0cm9rZQkyCQotIE1ham9yIHN0cm9rZQkzCQotIEFtYXVyb3NpcyBmdWdheAk0CQotIEZvdXIgdmVzc2VsIGRpc2Vhc2UJNQkKLSBWZXJ0ZWJyb2Jhc2lsYXJ5IFRJQQk3CQotIFJldGluYWwgaW5mYXJjdGlvbgk4CQotIFN5bXB0b21hdGljLCBidXQgYXNwZWNpZmljIHN5bXRvbXMJOQotIENvbnRyYWxhdGVyYWwgc3ltcHRvbWF0aWMgb2NjbHVzaW9uCTEwCQotIHJldGluYWwgaW5mYXJjdGlvbgkxMQkKLSBhcm1jbGF1ZGljYXRpb24gZHVlIHRvIG9jY2x1c2lvbiBzdWJjbGF2aWFuIGFydGVyeSwgQ0VBIG5lZWRlZCBmb3IgYnlwYXNzCTEyCQotIHJldGluYWwgaW5mYXJjdGlvbiArIFRJQXMJMTMJCi0gT2N1bGFyIGlzY2hlbWljIHN5bmRyb21lCTE0CQotIGlzY2hlbWlzY2ggZ2xhdWNvb20JMTUJCi0gc3ViY2xhdmlhbiBzdGVhbCBzeW5kcm9tZQkxNgkKLSBUR0EJMTcKCldlIHdpbGwgZ3JvdXAgYXMgZm9sbG93czoKCjEuIEFzeW1wdG9tYXRpYyA+IDAKMi4gVElBID4gMSwgNywgMTMKMy4gU3Ryb2tlID4gMiwgMwo0LiBPY3VsYXIgPiA0LCAxNCwgMTUKNS4gUmV0aW5hbCBpbmZhcmN0aW9uID4gOCwgMTEKNi4gT3RoZXIgPiA1LCA5LCAxMCwgMTIsIDE2LCAxNwoKCmBgYHtyIEZpeFN5bXB0b21zfQoKIyBGaXggc3ltcHRvbXMKCmF0dGFjaChBRURCKQpBRURCWywiU3ltcHRvbXMuNUciXSA8LSBOQQpBRURCJFN5bXB0b21zLjVHW3N5bXB0ID09IDBdIDwtICJBc3ltcHRvbWF0aWMiCkFFREIkU3ltcHRvbXMuNUdbc3ltcHQgPT0gMSB8IHN5bXB0ID09IDcgfCBzeW1wdCA9PSAxM10gPC0gIlRJQSIKQUVEQiRTeW1wdG9tcy41R1tzeW1wdCA9PSAyIHwgc3ltcHQgPT0gM10gPC0gIlN0cm9rZSIKQUVEQiRTeW1wdG9tcy41R1tzeW1wdCA9PSA0IHwgc3ltcHQgPT0gMTQgfCBzeW1wdCA9PSAxNSBdIDwtICJPY3VsYXIiCkFFREIkU3ltcHRvbXMuNUdbc3ltcHQgPT0gOCB8IHN5bXB0ID09IDExXSA8LSAiUmV0aW5hbCBpbmZhcmN0aW9uIgpBRURCJFN5bXB0b21zLjVHW3N5bXB0ID09IDUgfCBzeW1wdCA9PSA5IHwgc3ltcHQgPT0gMTAgfCBzeW1wdCA9PSAxMiB8IHN5bXB0ID09IDE2IHwgc3ltcHQgPT0gMTddIDwtICJPdGhlciIKCgojIEFzeW1wdFN5bXB0CkFFREJbLCJBc3ltcHRTeW1wdCJdIDwtIE5BCkFFREIkQXN5bXB0U3ltcHRbc3ltcHQgPT0gLTk5OV0gPC0gTkEKQUVEQiRBc3ltcHRTeW1wdFtzeW1wdCA9PSAwXSA8LSAiQXN5bXB0b21hdGljIgpBRURCJEFzeW1wdFN5bXB0W3N5bXB0ID09IDEgfCBzeW1wdCA9PSA3IHwgc3ltcHQgPT0gMTMgfCBzeW1wdCA9PSAyIHwgc3ltcHQgPT0gM10gPC0gIlN5bXB0b21hdGljIgpBRURCJEFzeW1wdFN5bXB0W3N5bXB0ID09IDQgfCBzeW1wdCA9PSAxNCB8IHN5bXB0ID09IDE1IHwgc3ltcHQgPT0gOCB8IHN5bXB0ID09IDExIHwgc3ltcHQgPT0gNSB8IHN5bXB0ID09IDkgfCBzeW1wdCA9PSAxMCB8IHN5bXB0ID09IDEyIHwgc3ltcHQgPT0gMTYgfCBzeW1wdCA9PSAxN10gPC0gIk9jdWxhciBhbmQgb3RoZXJzIgoKIyBBc3ltcHRTeW1wdApBRURCWywiQXN5bXB0U3ltcHQyRyJdIDwtIE5BCkFFREIkQXN5bXB0U3ltcHQyR1tzeW1wdCA9PSAtOTk5XSA8LSBOQQpBRURCJEFzeW1wdFN5bXB0Mkdbc3ltcHQgPT0gMF0gPC0gIkFzeW1wdG9tYXRpYyIKQUVEQiRBc3ltcHRTeW1wdDJHW3N5bXB0ID09IDEgfCBzeW1wdCA9PSA3IHwgc3ltcHQgPT0gMTMgfCBzeW1wdCA9PSAyIHwgc3ltcHQgPT0gMyB8IHN5bXB0ID09IDQgfCBzeW1wdCA9PSAxNCB8IHN5bXB0ID09IDE1IHwgc3ltcHQgPT0gOCB8IHN5bXB0ID09IDExIHwgc3ltcHQgPT0gNSB8IHN5bXB0ID09IDkgfCBzeW1wdCA9PSAxMCB8IHN5bXB0ID09IDEyIHwgc3ltcHQgPT0gMTYgfCBzeW1wdCA9PSAxN10gPC0gIlN5bXB0b21hdGljIgoKZGV0YWNoKEFFREIpCgojIHRhYmxlKEFFREIkc3ltcHQsIHVzZU5BID0gImlmYW55IikKIyB0YWJsZShBRURCJEFzeW1wdFN5bXB0MkcsIHVzZU5BID0gImlmYW55IikKIyB0YWJsZShBRURCJFN5bXB0b21zLjVHLCB1c2VOQSA9ICJpZmFueSIpCiMgCiMgdGFibGUoQUVEQiRBc3ltcHRTeW1wdDJHLCBBRURCJHN5bXB0LCB1c2VOQSA9ICJpZmFueSIpCiMgdGFibGUoQUVEQiRTeW1wdG9tcy41RywgQUVEQiRzeW1wdCwgdXNlTkEgPSAiaWZhbnkiKQp0YWJsZShBRURCJEFzeW1wdFN5bXB0MkcsIEFFREIkU3ltcHRvbXMuNUcsIHVzZU5BID0gImlmYW55IikKCiMgQUVEQi50ZW1wIDwtIHN1YnNldChBRURCLCAgc2VsZWN0ID0gYygiU1RVRFlfTlVNQkVSIiwgIlVQSUQiLCAiQWdlIiwgIkdlbmRlciIsICJIb3NwaXRhbCIsICJBcnRlcnlfc3VtbWFyeSIsICJzeW1wdCIsICJTeW1wdG9tcy41RyIsICJBc3ltcHRTeW1wdCIpKQojIHJlcXVpcmUobGFiZWxsZWQpCiMgQUVEQi50ZW1wJEdlbmRlciA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEdlbmRlcikKIyBBRURCLnRlbXAkSG9zcGl0YWwgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRIb3NwaXRhbCkKIyBBRURCLnRlbXAkQXJ0ZXJ5X3N1bW1hcnkgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSkKIyAKIyBEVDo6ZGF0YXRhYmxlKEFFREIudGVtcFsxOjEwLF0sIGNhcHRpb24gPSAiRXhjZXJwdCBvZiB0aGUgd2hvbGUgQUVEQi4iLCByb3duYW1lcyA9IEZBTFNFKQojIAojIHRhYmxlKEFFREIudGVtcCRTeW1wdG9tcy41RywgQUVEQi50ZW1wJEFzeW1wdFN5bXB0KQojIAojIHJtKEFFREIudGVtcCkKYGBgCgpXZSB3aWxsIGFsc28gZml4IHRoZSBfcGxhcXVlcGhlbm90eXBlc18gdmFyaWFibGUuICAKCkNvZGluZyBvZiBzeW1wdG9tcyBpcyBhcyBmb2xsb3dzOgoKLSBtaXNzaW5nCS05OTkJCi0gbm90IHJlbGV2YW50IC04ODgKLSBmaWJyb3VzCTEJCi0gZmlicm9hdGhlcm9tYXRvdXMJMgkKLSBhdGhlcm9tYXRvdXMJMwkKCgpgYGB7ciBGaXhQbGFxdWVQaGVub3R5cGVzfQoKIyBGaXggcGxhcXVlcGhlbm90eXBlcwphdHRhY2goQUVEQikKQUVEQlssIk92ZXJhbGxQbGFxdWVQaGVub3R5cGUiXSA8LSBOQQpBRURCJE92ZXJhbGxQbGFxdWVQaGVub3R5cGVbcGxhcXVlcGhlbm90eXBlID09IC05OTldIDwtIE5BCkFFREIkT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZVtwbGFxdWVwaGVub3R5cGUgPT0gLTk5OV0gPC0gTkEKQUVEQiRPdmVyYWxsUGxhcXVlUGhlbm90eXBlW3BsYXF1ZXBoZW5vdHlwZSA9PSAxXSA8LSAiZmlicm91cyIKQUVEQiRPdmVyYWxsUGxhcXVlUGhlbm90eXBlW3BsYXF1ZXBoZW5vdHlwZSA9PSAyXSA8LSAiZmlicm9hdGhlcm9tYXRvdXMiCkFFREIkT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZVtwbGFxdWVwaGVub3R5cGUgPT0gM10gPC0gImF0aGVyb21hdG91cyIKZGV0YWNoKEFFREIpCgojIEFFREIudGVtcCA8LSBzdWJzZXQoQUVEQiwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAicGxhcXVlcGhlbm90eXBlIiwgIk92ZXJhbGxQbGFxdWVQaGVub3R5cGUiKSkKIyByZXF1aXJlKGxhYmVsbGVkKQojIEFFREIudGVtcCRHZW5kZXIgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRHZW5kZXIpCiMgQUVEQi50ZW1wJEhvc3BpdGFsIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkSG9zcGl0YWwpCiMgQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5IDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkQXJ0ZXJ5X3N1bW1hcnkpCiMgCiMgRFQ6OmRhdGF0YWJsZShBRURCLnRlbXBbMToxMCxdLCBjYXB0aW9uID0gIkV4Y2VycHQgb2YgdGhlIHdob2xlIEFFREIuIiwgcm93bmFtZXMgPSBGQUxTRSkKIyAKIyBybShBRURCLnRlbXApCgpgYGAKCldlIHdpbGwgYWxzbyBmaXggdGhlIF9kaWFiZXRlc18gc3RhdHVzIHZhcmlhYmxlLgoKYGBge3IgRml4RGlhYmV0ZXN9CgojIEZpeCBkaWFiZXRlcwphdHRhY2goQUVEQikKQUVEQlssIkRpYWJldGVzU3RhdHVzIl0gPC0gTkEKQUVEQiREaWFiZXRlc1N0YXR1c1tETS5jb21wb3NpdGUgPT0gLTk5OV0gPC0gTkEKQUVEQiREaWFiZXRlc1N0YXR1c1tETS5jb21wb3NpdGUgPT0gMF0gPC0gIkNvbnRyb2wgKG5vIERpYWJldGVzIER4L01lZCkiCkFFREIkRGlhYmV0ZXNTdGF0dXNbRE0uY29tcG9zaXRlID09IDFdIDwtICJEaWFiZXRlcyIKZGV0YWNoKEFFREIpCgojIEFFREIudGVtcCA8LSBzdWJzZXQoQUVEQiwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiRE0uY29tcG9zaXRlIiwgIkRpYWJldGVzU3RhdHVzIikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIEFFREIudGVtcCREaWFiZXRlc1N0YXR1cyA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJERpYWJldGVzU3RhdHVzKQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgcm0oQUVEQi50ZW1wKQoKYGBgCgoKV2Ugd2lsbCBhbHNvIGZpeCB0aGUgX3Ntb2tpbmdfIHN0YXR1cyB2YXJpYWJsZS4gV2UgYXJlIGludGVyZXN0ZWQgaW4gd2hldGhlciBzb21lb25lIG5ldmVyLCBldmVyIG9yIGlzIGN1cnJlbnRseSAoYXQgdGhlIHRpbWUgb2YgaW5jbHVzaW9uKSBzbW9raW5nLiBUaGlzIGlzIGJhc2VkIG9uIHRoZSBxdWVzdGlvbm5haXJlLiAKCi0gYGRpZXQ4MDFgOiBhcmUgeW91IGEgc21va2VyPwotIGBkaWV0ODAyYDogZGlkIHlvdSBzbW9rZSBpbiB0aGUgcGFzdD8KCldlIGFscmVhZHkgaGF2ZSBzb21lIHZhcmlhYmxlcyBpbmRpY2F0aW5nIHNtb2tpbmcgc3RhdHVzOgoKLSBgU21va2luZ1JlcG9ydGVkYDogcGF0aWVudCBoYXMgcmVwb3J0ZWQgdG8gc21va2UuCi0gYFNtb2tpbmdZZWFyT1JgOiBzbW9raW5nIGluIHRoZSB5ZWFyIG9mIHN1cmdlcnk/Ci0gYFNtb2tlckN1cnJlbnRgOiBjdXJyZW50bHkgc21va2luZz8KCgoKYGBge3IgRml4U21va2luZ30KcmVxdWlyZShsYWJlbGxlZCkKQUVEQiRkaWV0ODAxIDwtIHRvX2ZhY3RvcihBRURCJGRpZXQ4MDEpCkFFREIkZGlldDgwMiA8LSB0b19mYWN0b3IoQUVEQiRkaWV0ODAyKQpBRURCJGRpZXQ4MDUgPC0gdG9fZmFjdG9yKEFFREIkZGlldDgwNSkKQUVEQiRTbW9raW5nUmVwb3J0ZWQgPC0gdG9fZmFjdG9yKEFFREIkU21va2luZ1JlcG9ydGVkKQpBRURCJFNtb2tlckN1cnJlbnQgPC0gdG9fZmFjdG9yKEFFREIkU21va2VyQ3VycmVudCkKQUVEQiRTbW9raW5nWWVhck9SIDwtIHRvX2ZhY3RvcihBRURCJFNtb2tpbmdZZWFyT1IpCgojIHRhYmxlKEFFREIkZGlldDgwMSkKIyB0YWJsZShBRURCJGRpZXQ4MDIpCiMgdGFibGUoQUVEQiRTbW9raW5nUmVwb3J0ZWQpCiMgdGFibGUoQUVEQiRTbW9rZXJDdXJyZW50KQojIHRhYmxlKEFFREIkU21va2luZ1llYXJPUikKIyB0YWJsZShBRURCJFNtb2tpbmdSZXBvcnRlZCwgQUVEQiRTbW9rZXJDdXJyZW50LCB1c2VOQSA9ICJpZmFueSIsIGRubiA9IGMoIlJlcG9ydGVkIHNtb2tpbmciLCAiQ3VycmVudCBzbW9rZXIiKSkKIyAKIyB0YWJsZShBRURCJGRpZXQ4MDEsIEFFREIkZGlldDgwMiwgdXNlTkEgPSAiaWZhbnkiLCBkbm4gPSBjKCJTbW9rZXIiLCAiUGFzdCBzbW9rZXIiKSkKCmNhdCgiXG5GaXhpbmcgc21va2luZyBzdGF0dXMuXG4iKQphdHRhY2goQUVEQikKQUVEQlssIlNtb2tlclN0YXR1cyJdIDwtIE5BCkFFREIkU21va2VyU3RhdHVzW2RpZXQ4MDIgPT0gImRvbid0IGtub3ciXSA8LSAiTmV2ZXIgc21va2VkIgpBRURCJFNtb2tlclN0YXR1c1tkaWV0ODAyID09ICJJIHN0aWxsIHNtb2tlIl0gPC0gIkN1cnJlbnQgc21va2VyIgpBRURCJFNtb2tlclN0YXR1c1tTbW9rZXJDdXJyZW50ID09ICJubyIgJiBkaWV0ODAyID09ICJubyJdIDwtICJOZXZlciBzbW9rZWQiCkFFREIkU21va2VyU3RhdHVzW1Ntb2tlckN1cnJlbnQgPT0gIm5vIiAmIGRpZXQ4MDIgPT0gInllcyJdIDwtICJFeC1zbW9rZXIiCkFFREIkU21va2VyU3RhdHVzW1Ntb2tlckN1cnJlbnQgPT0gInllcyJdIDwtICJDdXJyZW50IHNtb2tlciIKQUVEQiRTbW9rZXJTdGF0dXNbU21va2VyQ3VycmVudCA9PSAibm8gZGF0YSBhdmFpbGFibGUvbWlzc2luZyJdIDwtIE5BCiMgQUVEQiRTbW9rZXJTdGF0dXNbaXMubmEoU21va2VyQ3VycmVudCldIDwtICJOZXZlciBzbW9rZWQiCmRldGFjaChBRURCKQoKY2F0KCJcbiogQ3VycmVudCBzbW9raW5nIHN0YXR1cy5cbiIpCnRhYmxlKEFFREIkU21va2VyQ3VycmVudCwKICAgICAgdXNlTkEgPSAiaWZhbnkiLCAKICAgICAgZG5uID0gYygiQ3VycmVudCBzbW9rZXIiKSkKCmNhdCgiXG4qIFVwZGF0ZWQgc21va2luZyBzdGF0dXMuXG4iKQp0YWJsZShBRURCJFNtb2tlclN0YXR1cywKICAgICAgdXNlTkEgPSAiaWZhbnkiLCAKICAgICAgZG5uID0gYygiVXBkYXRlZCBzbW9raW5nIHN0YXR1cyIpKQoKY2F0KCJcbiogQ29tcGFyaW5nIHRvICdTbW9rZXJDdXJyZW50Jy5cbiIpCnRhYmxlKEFFREIkU21va2VyU3RhdHVzLCBBRURCJFNtb2tlckN1cnJlbnQsIAogICAgICB1c2VOQSA9ICJpZmFueSIsIAogICAgICBkbm4gPSBjKCJVcGRhdGVkIHNtb2tpbmcgc3RhdHVzIiwgIkN1cnJlbnQgc21va2VyIikpCgojIEFFREIudGVtcCA8LSBzdWJzZXQoQUVEQiwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiRE0uY29tcG9zaXRlIiwgIkRpYWJldGVzU3RhdHVzIikpCiMgcmVxdWlyZShsYWJlbGxlZCkKIyBBRURCLnRlbXAkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkR2VuZGVyKQojIEFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQojIEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5KQojIEFFREIudGVtcCREaWFiZXRlc1N0YXR1cyA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJERpYWJldGVzU3RhdHVzKQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgcm0oQUVEQi50ZW1wKQoKCmBgYAoKV2Ugd2lsbCBhbHNvIGZpeCB0aGUgX2FsY29ob2xfIHN0YXR1cyB2YXJpYWJsZS4KCgpgYGB7ciBGaXhBbGNvaG9sfQoKIyBGaXggZGlhYmV0ZXMKYXR0YWNoKEFFREIpCkFFREJbLCJBbGNvaG9sVXNlIl0gPC0gTkEKQUVEQiRBbGNvaG9sVXNlW2RpZXQ4MTAgPT0gLTk5OV0gPC0gTkEKQUVEQiRBbGNvaG9sVXNlW2RpZXQ4MTAgPT0gMF0gPC0gIk5vIgpBRURCJEFsY29ob2xVc2VbZGlldDgxMCA9PSAxXSA8LSAiWWVzIgpkZXRhY2goQUVEQikKCiMgQUVEQi50ZW1wIDwtIHN1YnNldChBRURCLCAgc2VsZWN0ID0gYygiU1RVRFlfTlVNQkVSIiwgIlVQSUQiLCAiQWdlIiwgIkdlbmRlciIsICJIb3NwaXRhbCIsICJBcnRlcnlfc3VtbWFyeSIsICJkaWV0ODEwIiwgIkFsY29ob2xVc2UiKSkKIyByZXF1aXJlKGxhYmVsbGVkKQojIEFFREIudGVtcCRHZW5kZXIgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRHZW5kZXIpCiMgQUVEQi50ZW1wJEhvc3BpdGFsIDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkSG9zcGl0YWwpCiMgQUVEQi50ZW1wJEFydGVyeV9zdW1tYXJ5IDwtIHRvX2ZhY3RvcihBRURCLnRlbXAkQXJ0ZXJ5X3N1bW1hcnkpCiMgQUVEQi50ZW1wJEFsY29ob2xVc2UgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRBbGNvaG9sVXNlKQojIAojIERUOjpkYXRhdGFibGUoQUVEQi50ZW1wWzE6MTAsXSwgY2FwdGlvbiA9ICJFeGNlcnB0IG9mIHRoZSB3aG9sZSBBRURCLiIsIHJvd25hbWVzID0gRkFMU0UpCiMgCiMgcm0oQUVEQi50ZW1wKQoKCmBgYAoKCldlIHdpbGwgYWxzbyBmaXggYW5kIGludmVyc2UtcmFuayBub3JtYWwgdHJhbnNmb3JtIHRoZSBjb250aW51b3VzIChtYW51YWxseSkgc2NvcmVkIHBsYXF1ZSBwaGVub3R5cGVzLgoKYGBge3IgSVJOVCBQbGFxdWVQaGVub3R5cGVzfQpBRURCJG1hY21lYW4wIDwtIGFzLm51bWVyaWMoQUVEQiRtYWNtZWFuMCkKQUVEQiRzbWNtZWFuMCA8LSBhcy5udW1lcmljKEFFREIkc21jbWVhbjApCkFFREIkbmV1dHJvcGhpbHMgPC0gYXMubnVtZXJpYyhBRURCJG5ldXRyb3BoaWxzKQpBRURCJE1hc3RfY2VsbHNfcGxhcXVlIDwtIGFzLm51bWVyaWMoQUVEQiRNYXN0X2NlbGxzX3BsYXF1ZSkKQUVEQiR2ZXNzZWxfZGVuc2l0eV9hdmVyYWdlZCA8LSBhcy5udW1lcmljKEFFREIkdmVzc2VsX2RlbnNpdHlfYXZlcmFnZWQpCgpBRURCJE1BQ19yYW5rTm9ybSA8LSBxbm9ybSgocmFuayhBRURCJG1hY21lYW4wLCBuYS5sYXN0ID0gImtlZXAiKSAtIDAuNSkgLyBzdW0oIWlzLm5hKEFFREIkbWFjbWVhbjApKSkKQUVEQiRTTUNfcmFua05vcm0gPC0gcW5vcm0oKHJhbmsoQUVEQiRzbWNtZWFuMCwgbmEubGFzdCA9ICJrZWVwIikgLSAwLjUpIC8gc3VtKCFpcy5uYShBRURCJHNtY21lYW4wKSkpCkFFREIkTmV1dHJvcGhpbHNfcmFua05vcm0gPC0gcW5vcm0oKHJhbmsoQUVEQiRuZXV0cm9waGlscywgbmEubGFzdCA9ICJrZWVwIikgLSAwLjUpIC8gc3VtKCFpcy5uYShBRURCJG5ldXRyb3BoaWxzKSkpCkFFREIkTWFzdENlbGxzX3JhbmtOb3JtIDwtIHFub3JtKChyYW5rKEFFREIkTWFzdF9jZWxsc19wbGFxdWUsIG5hLmxhc3QgPSAia2VlcCIpIC0gMC41KSAvIHN1bSghaXMubmEoQUVEQiRNYXN0X2NlbGxzX3BsYXF1ZSkpKQpBRURCJFZlc3NlbERlbnNpdHlfcmFua05vcm0gPC0gcW5vcm0oKHJhbmsoQUVEQiR2ZXNzZWxfZGVuc2l0eV9hdmVyYWdlZCwgbmEubGFzdCA9ICJrZWVwIikgLSAwLjUpIC8gc3VtKCFpcy5uYShBRURCJHZlc3NlbF9kZW5zaXR5X2F2ZXJhZ2VkKSkpCgpgYGAKCgpgYGB7ciBJUk5UIFBsYXF1ZVBoZW5vdHlwZXM6IFZpc3VhbGlzYXRpb259CmxpYnJhcnkobGFiZWxsZWQpCkFFREIkR2VuZGVyIDwtIHRvX2ZhY3RvcihBRURCJEdlbmRlcikKZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAibWFjbWVhbjAiLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIiUgb2YgbWFjcm9waGFnZXMgKENENjgpIiwKICAgICAgICAgICAgICAgICAgICB4bGFiID0gIiUgcGVyIHJlZ2lvbiBvZiBpbnRlcmVzdCIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpnZ3B1YnI6OmdnaGlzdG9ncmFtKEFFREIsICJNQUNfcmFua05vcm0iLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIiUgb2YgbWFjcm9waGFnZXMgKENENjgpIiwKICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiJSBwZXIgcmVnaW9uIG9mIGludGVyZXN0XG5pbnZlcnNlLXJhbmsgbm9ybWFsaXplZCBudW1iZXIiLCAKICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpKQoKZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAic21jbWVhbjAiLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIiUgb2Ygc21vb3RoIG11c2NsZSBjZWxscyAoU01BKSIsCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIlIHBlciByZWdpb24gb2YgaW50ZXJlc3QiLCAKICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpKQoKZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAiU01DX3JhbmtOb3JtIiwgCiAgICAgICAgICAgICAgICAgICAgIyB5ID0gIi4uY291bnQuLiIsIAogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgICBmaWxsID0gIkdlbmRlciIsCiAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMxMjkwRDkiLCAiI0RCMDAzRiIpLCAKICAgICAgICAgICAgICAgICAgICBhZGQgPSAibWVkaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgI2FkZF9kZW5zaXR5ID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICNhZGQucGFyYW1zID0gIGxpc3QoY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9IDIpLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICIlIG9mIHNtb290aCBtdXNjbGUgY2VsbHMgKFNNQSkiLAogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIlIHBlciByZWdpb24gb2YgaW50ZXJlc3RcbmludmVyc2UtcmFuayBub3JtYWxpemVkIG51bWJlciIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpnZ3B1YnI6OmdnaGlzdG9ncmFtKEFFREIsICJuZXV0cm9waGlscyIsIAogICAgICAgICAgICAgICAgICAgICMgeSA9ICIuLmNvdW50Li4iLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMTI5MEQ5IiwgIiNEQjAwM0YiKSwgCiAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lZGlhbiIsIAogICAgICAgICAgICAgICAgICAgICNhZGRfZGVuc2l0eSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAjYWRkLnBhcmFtcyA9ICBsaXN0KGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAibnVtYmVyIG9mIG5ldXRyb3BoaWxzIChDRDY2YikiLAogICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiY291bnRzIHBlciBwbGFxdWUiLCAKICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpKQoKZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIm51bWJlciBvZiBuZXV0cm9waGlscyAoQ0Q2NmIpIiwKICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiY291bnRzIHBlciBwbGFxdWVcbmludmVyc2UtcmFuayBub3JtYWxpemVkIG51bWJlciIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCgpnZ3B1YnI6OmdnaGlzdG9ncmFtKEFFREIsICJNYXN0X2NlbGxzX3BsYXF1ZSIsIAogICAgICAgICAgICAgICAgICAgICMgeSA9ICIuLmNvdW50Li4iLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJHZW5kZXIiLAogICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMTI5MEQ5IiwgIiNEQjAwM0YiKSwgCiAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lZGlhbiIsIAogICAgICAgICAgICAgICAgICAgICNhZGRfZGVuc2l0eSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAjYWRkLnBhcmFtcyA9ICBsaXN0KGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAyKSwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAibnVtYmVyIG9mIG1hc3QgY2VsbHMiLAogICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiY291bnRzIHBlciBwbGFxdWUiLCAKICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpKQoKZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgCiAgICAgICAgICAgICAgICAgICAgIyB5ID0gIi4uY291bnQuLiIsIAogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgICBmaWxsID0gIkdlbmRlciIsCiAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMxMjkwRDkiLCAiI0RCMDAzRiIpLCAKICAgICAgICAgICAgICAgICAgICBhZGQgPSAibWVkaWFuIiwgCiAgICAgICAgICAgICAgICAgICAgI2FkZF9kZW5zaXR5ID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICNhZGQucGFyYW1zID0gIGxpc3QoY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9IDIpLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJudW1iZXIgb2YgbWFzdCBjZWxscyIsCiAgICAgICAgICAgICAgICAgICB4bGFiID0gImNvdW50cyBwZXIgcGxhcXVlXG5pbnZlcnNlLXJhbmsgbm9ybWFsaXplZCBudW1iZXIiLCAKICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpKQoKZ2dwdWJyOjpnZ2hpc3RvZ3JhbShBRURCLCAidmVzc2VsX2RlbnNpdHlfYXZlcmFnZWQiLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIm51bWJlciBvZiBpbnRyYXBsYXF1ZSBuZW92ZXNzZWxzIiwKICAgICAgICAgICAgICAgICAgICB4bGFiID0gImNvdW50cyBwZXIgMy00IGhvdHNwb3RzIiwgCiAgICAgICAgICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkKCmdncHVicjo6Z2doaXN0b2dyYW0oQUVEQiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLCAKICAgICAgICAgICAgICAgICAgICAjIHkgPSAiLi5jb3VudC4uIiwgCiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzEyOTBEOSIsICIjREIwMDNGIiksIAogICAgICAgICAgICAgICAgICAgIGFkZCA9ICJtZWRpYW4iLCAKICAgICAgICAgICAgICAgICAgICAjYWRkX2RlbnNpdHkgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgI2FkZC5wYXJhbXMgPSAgbGlzdChjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gMiksIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIm51bWJlciBvZiBpbnRyYXBsYXF1ZSBuZW92ZXNzZWxzIiwKICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiY291bnRzIHBlciAzLTQgaG90c3BvdHNcbmludmVyc2UtcmFuayBub3JtYWxpemVkIG51bWJlciIsIAogICAgICAgICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpCmBgYAoKCgpIZXJlIHdlIGNhbGN1bGF0ZSB0aGUgX3BsYXF1ZSBpbnN0YWJpbGl0eS92dWxuZXJhYmlsaXR5XyBpbmRleAoKYGBge3IgUGxhcXVlIFZ1bG5lcmFiaWxpdHl9CgojIFBsYXF1ZSB2dWxuZXJhYmlsaXR5CgojIFNQU1MgY29kZQoKIyAKIyAqKiogc3ludGF4LSBQbGFxdWUgdnVsbmVyYWJpbGl0eSoqLgojIENPTVBVVEUgTWFjcm9faW5zdGFiID0gLTk5OS4KIyBJRiBtYWNyb3BoYWdlcy5iaW49MiBNYWNyb19pbnN0YWI9MS4KIyBJRiBtYWNyb3BoYWdlcy5iaW49MSBNYWNyb19pbnN0YWI9MC4KIyBFWEVDVVRFLgojIAojIENPTVBVVEUgRmF0MTBfaW5zdGFiID0gLTk5OS4KIyBJRiBGYXQuYmluXzEwPTIgRmF0MTBfaW5zdGFiPTEuCiMgSUYgRmF0LmJpbl8xMD0xIEZhdDEwX2luc3RhYj0wLgojIEVYRUNVVEUuCiMgCiMgQ09NUFVURSBjb2xsX2luc3RhYj0tOTk5LgojIElGIENvbGxhZ2VuLmJpbj0yIGNvbGxfaW5zdGFiPTAuCiMgSUYgQ29sbGFnZW4uYmluPTEgY29sbF9pbnN0YWI9MS4KIyBFWEVDVVRFLgojIAojIAojIENPTVBVVEUgU01DX2luc3RhYj0tOTk5LgojIElGIFNNQy5iaW49MiBTTUNfaW5zdGFiPTAuCiMgSUYgU01DLmJpbj0xIFNNQ19pbnN0YWI9MS4KIyBFWEVDVVRFLgojIAojIENPTVBVVEUgSVBIX2luc3RhYj0tOTk5LgojIElGIElQSC5iaW49MCBJUEhfaW5zdGFiPTAuCiMgSUYgSVBILmJpbj0xIElQSF9pbnN0YWI9MS4KIyBFWEVDVVRFLgojIAojIENPTVBVVEUgSW5zdGFiaWxpdHk9TWFjcm9faW5zdGFiICsgRmF0MTBfaW5zdGFiICsgIGNvbGxfaW5zdGFiICsgU01DX2luc3RhYiArIElQSF9pbnN0YWIuCiMgRVhFQ1VURS4KCnJlcXVpcmUobGFiZWxsZWQpCkFFREIkTWFjcm9waGFnZXMuYmluIDwtIHRvX2ZhY3RvcihBRURCJE1hY3JvcGhhZ2VzLmJpbikKQUVEQiRTTUMuYmluIDwtIHRvX2ZhY3RvcihBRURCJFNNQy5iaW4pCkFFREIkSVBILmJpbiA8LSB0b19mYWN0b3IoQUVEQiRJUEguYmluKQpBRURCJENhbGMuYmluIDwtIHRvX2ZhY3RvcihBRURCJENhbGMuYmluKQpBRURCJENvbGxhZ2VuLmJpbiA8LSB0b19mYWN0b3IoQUVEQiRDb2xsYWdlbi5iaW4pCkFFREIkRmF0LmJpbl8xMCA8LSB0b19mYWN0b3IoQUVEQiRGYXQuYmluXzEwKQpBRURCJEZhdC5iaW5fNDAgPC0gdG9fZmFjdG9yKEFFREIkRmF0LmJpbl80MCkKCnRhYmxlKEFFREIkTWFjcm9waGFnZXMuYmluKQp0YWJsZShBRURCJEZhdC5iaW5fMTApCnRhYmxlKEFFREIkQ29sbGFnZW4uYmluKQp0YWJsZShBRURCJFNNQy5iaW4pCnRhYmxlKEFFREIkSVBILmJpbikKCiMgRml4IHBsYXF1ZXBoZW5vdHlwZXMKYXR0YWNoKEFFREIpCiMgbWFjIGluc3RhYmlsaXR5CkFFREJbLCJNQUNfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJE1BQ19JbnN0YWJpbGl0eVtNYWNyb3BoYWdlcy5iaW4gPT0gLTk5OV0gPC0gTkEKQUVEQiRNQUNfSW5zdGFiaWxpdHlbTWFjcm9waGFnZXMuYmluID09ICJuby9taW5vciJdIDwtIDAKQUVEQiRNQUNfSW5zdGFiaWxpdHlbTWFjcm9waGFnZXMuYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtIDEKCiMgZmF0IGluc3RhYmlsaXR5CkFFREJbLCJGQVQxMF9JbnN0YWJpbGl0eSJdIDwtIE5BCkFFREIkRkFUMTBfSW5zdGFiaWxpdHlbRmF0LmJpbl8xMCA9PSAtOTk5XSA8LSBOQQpBRURCJEZBVDEwX0luc3RhYmlsaXR5W0ZhdC5iaW5fMTAgPT0gIiA8MTAlIl0gPC0gMApBRURCJEZBVDEwX0luc3RhYmlsaXR5W0ZhdC5iaW5fMTAgPT0gIiA+MTAlIl0gPC0gMQoKIyBjb2wgaW5zdGFiaWxpdHkgCkFFREJbLCJDT0xfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJENPTF9JbnN0YWJpbGl0eVtDb2xsYWdlbi5iaW4gPT0gLTk5OV0gPC0gTkEKQUVEQiRDT0xfSW5zdGFiaWxpdHlbQ29sbGFnZW4uYmluID09ICJuby9taW5vciJdIDwtIDEKQUVEQiRDT0xfSW5zdGFiaWxpdHlbQ29sbGFnZW4uYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtIDAKCiMgc21jIGluc3RhYmlsaXR5CkFFREJbLCJTTUNfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJFNNQ19JbnN0YWJpbGl0eVtTTUMuYmluID09IC05OTldIDwtIE5BCkFFREIkU01DX0luc3RhYmlsaXR5W1NNQy5iaW4gPT0gIm5vL21pbm9yIl0gPC0gMQpBRURCJFNNQ19JbnN0YWJpbGl0eVtTTUMuYmluID09ICJtb2RlcmF0ZS9oZWF2eSJdIDwtIDAKCiMgaXBoIGluc3RhYmlsaXR5CkFFREJbLCJJUEhfSW5zdGFiaWxpdHkiXSA8LSBOQQpBRURCJElQSF9JbnN0YWJpbGl0eVtJUEguYmluID09IC05OTldIDwtIE5BCkFFREIkSVBIX0luc3RhYmlsaXR5W0lQSC5iaW4gPT0gIm5vIl0gPC0gMApBRURCJElQSF9JbnN0YWJpbGl0eVtJUEguYmluID09ICJ5ZXMiXSA8LSAxCgpkZXRhY2goQUVEQikKCnRhYmxlKEFFREIkTUFDX0luc3RhYmlsaXR5LCB1c2VOQSA9ICJpZmFueSIpCnRhYmxlKEFFREIkRkFUMTBfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKdGFibGUoQUVEQiRDT0xfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKdGFibGUoQUVEQiRTTUNfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKdGFibGUoQUVEQiRJUEhfSW5zdGFiaWxpdHksIHVzZU5BID0gImlmYW55IikKCiMgY3JlYXRpbmcgdnVsbmVyYWJpbGl0eSBpbmRleApBRURCIDwtIEFFREIgJT4lIG11dGF0ZShQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9IGZhY3Rvcihyb3dTdW1zKC5bZ3JlcCgiX0luc3RhYmlsaXR5IiwgbmFtZXMoLikpXSwgbmEucm0gPSBUUlVFKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQoKdGFibGUoQUVEQiRQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCwgdXNlTkEgPSAiaWZhbnkiKQoKIyBzdHIoQUVEQiRQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCkKCmBgYAojIyMgUHJlcGFyZSBiYXNlbGluZSBjaGFyYWN0ZXJpc3RpY3MKCldlIGFyZSBpbnRlcmVzdGVkIGluIHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIGF0IGJhc2VsaW5lLgoKLSBBZ2UgKHllYXJzKQotIEZlbWFsZSBzZXggKE4sICUpCi0gSHlwZXJ0ZW5zaW9uIChOLCAlKQotIFNCUCAobW1IZykKLSBEQlAgKG1tSGcpCi0gRGlhYmV0ZXMgbWVsbGl0dXMgKE4sICUpCi0gVG90YWwgY2hvbGVzdGVyb2wgbGV2ZWxzIChtZy9kTCkKLSBMREwgY2hvbGVzdGVyb2wgbGV2ZWxzIChtZy9kTCkKLSBIREwgY2hvbGVzdGVyb2wgbGV2ZWxzIChtZy9kTCkKLSBUcmlnbHljZXJpZGUgbGV2ZWxzIChtZy9kTCkKLSBVc2Ugb2Ygc3RhdGlucyAoTiwgJSkKLSBVc2Ugb2YgYW50aXBsYXRlbGV0IGRydWdzIChOLCAlKQotIEJNSSAoa2cvbcKyKQotIFNtb2tpbmcgc3RhdHVzIChOLCAlKQogIC0gTmV2ZXIgc21va2VycwogIC0gRXgtc21va2VycwogIC0gQ3VycmVudCBzbW9rZXJzCi0gSGlzdG9yeSBvZiBDQUQgKE4sICUpCi0gSGlzdG9yeSBvZiBQQUQgKE4sICUpCi0gQ2xpbmljYWwgbWFuaWZlc3RhdGlvbnMKICAtIEFzeW1wdG9tYXRpYwogIC0gQW1hdXJvc2lzIGZ1Z2F4CiAgLSBUSUEKICAtIFN0cm9rZQotIGVHRlIgKG1ML21pbi8xLjczIG3CsikKLSBzdGVub3NpcwotIHllYXIgb2Ygc3VyZ2VyeQotIHBsYXF1ZSBjaGFyYWN0ZXJpc3RpY3MKCgpgYGB7ciBCYXNlbGluZSBBRURCOiBwcmVwYXJhdGlvbn0KY2F0KCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKQpjYXQoIlNFTEVDVElPTiBUSEUgU0hJWlpMRVxuIikKCiMjIyBBcnRlcnkgbGV2ZWxzCiMgQUVkYXRhJEFydGVyeV9zdW1tYXJ5OiAKIyAgICAgICAgICAgdmFsdWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsCiMgTk9UIFVTRSAtIDAgTm8gYXJ0ZXJ5IGtub3duICh5ZXQpLCBubyBzdXJnZXJ5IChwYXRpZW50IGlsbCwgZGllZCwgZXhpdGVkIHN0dWR5KSwgcmUtbnVtYmVyZWQgdG8gQUFBCiMgVVNFIC0gMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcm90aWQgKGxlZnQgJiByaWdodCkKIyBVU0UgLSAyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZW1vcmFsL2lsaWFjIChsZWZ0LCByaWdodCBvciBib3RoIHNpZGVzKQojIE5PVCBVU0UgLSAzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlciBjYXJvdGlkIGFydGVyaWVzIChjb21tb24sIGV4dGVybmFsKQojIE5PVCBVU0UgLSA0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXJvdGlkIGJ5cGFzcyBhbmQgaW5qdXJ5IChsZWZ0LCByaWdodCBvciBib3RoIHNpZGVzKQojIE5PVCBVU0UgLSA1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ldXJ5c21hdGEgKGNhcm90aWQgJiBmZW1vcmFsKQojIE5PVCBVU0UgLSA2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhb3J0YQojIE5PVCBVU0UgLSA3ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlciBhcnRlcmllcyAocmVuYWwsIHBvcGxpdGVhbCwgdmVydGVicmFsKQojIE5PVCBVU0UgLSA4ICAgICAgICAgICAgICAgICAgICAgICAgZmVtb3JhbCBieXBhc3MsIGFuZ2lvc2VhbCBhbmQgaW5qdXJ5IChsZWZ0LCByaWdodCBvciBib3RoIHNpZGVzKQoKIyMjIEFFZGF0YSRpbmZvcm1lZGNvbnNlbnQKIyAgICAgICAgICAgdmFsdWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwKIyBOT1QgVVNFIC0gLTk5OSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWlzc2luZwojIE5PVCBVU0UgLSAwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vLCBkaWVkCiMgVVNFIC0gMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcwojIFVTRSAtIDIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUKIyBVU0UgLSAzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBoZWFsdGggdHJlYXRtZW50CiMgVVNFIC0gNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcwojIE5PVCBVU0UgLSA1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzCiMgTk9UIFVTRSAtIDYgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBVU0UgLSA3ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgVVNFIC0gOCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gcXVlc3Rpb25uYWlyZXMsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZQojIE5PVCBVU0UgLSA5ICAgICAgICAgICAgICAgICAgeWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJpY2FsIGJ1c2luZXNzCiMgVVNFIC0gMTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBOT1QgVVNFIC0gMTEgeWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBVU0UgLSAxMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudAojIE5PVCBVU0UgLSAxMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHRpc3N1ZSwgbm8gaGVhbHRoIHRyZWF0bWVudAojIE5PVCBVU0UgLSAxNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcwojIE5PVCBVU0UgLSAxNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyB0aXNzdWUsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZQojIE5PVCBVU0UgLSAxNiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHRpc3N1ZQojIFVTRSAtIDE3ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzCiMgVVNFIC0gMTggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBVU0UgLSAxOSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcwojIFVTRSAtIDIwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHF1ZXN0aW9ubmFpcmVzCiMgTk9UIFVTRSAtIDIxICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvCiMgTk9UIFVTRSAtIDIyICAgICAgICAgICAgICAgICAgeWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJjaWFsIGJ1c2luZXNzCiMgVVNFIC0gMjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBtZWRpY2FsIGluZm8KIyBVU0UgLSAyNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBxdWVzdGlvbm5haXJlcywgbm8gY29tbWVyY2lhbCBidXNpbmVzcwojIFVTRSAtIDI1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvCiMgVVNFIC0gMjYgICAgICAgICAgICAgICAgICB5ZXMsIG5vIHF1ZXN0aW9ubmFpcmVzLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MKIyBVU0UgLSAyNyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllcywgIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbwojIE5PVCBVU0UgLSAyOCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm8sIGRvZXNuJ3Qgd2FudCB0bwojIE5PVCBVU0UgLSAyOSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vLCB1bmFibGUgdG8gc2lnbgojIE5PVCBVU0UgLSAzMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vLCBubyByZWFjdGlvbgojIE5PVCBVU0UgLSAzMSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBubywgbG9zdAojIE5PVCBVU0UgLSAzMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBubywgdG9vIG9sZAojIE5PVCBVU0UgLSAzNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVzLCBubyBtZWRpY2FsIGluZm8sIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZQojIE5PVCBVU0UgLSAzNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKQojIFVTRSAtIDM2ICAgICAgICAgICAgICAgICAgICB5ZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcywgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlCiMgTk9UIFVTRSAtIDM3ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm8sIGVuZHBvaW50CiMgVVNFIC0gMzggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWwgbmlldHMgaW52dWxsZW4sIHdlbCBhbGxlcyBnZWJydWlrZW4KIyBVU0UgLSAzOSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWNvbmQgaW5mb3JtZWQgY29uY2VudHM6IHllcywgbm8gY29tbWVyY2lhbCBidXNpbmVzcwojIE5PVCBVU0UgLSA0MCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vb2l0IGdlaW5jbHVkZWVyZAoKY2F0KCItIHNhbml0eSBjaGVja2luZyBQUklPUiB0byBzZWxlY3Rpb24iKQpsaWJyYXJ5KGRhdGEudGFibGUpCnJlcXVpcmUobGFiZWxsZWQpCmFlLmdlbmRlciA8LSB0b19mYWN0b3IoQUVEQiRHZW5kZXIpCmFlLmhvc3BpdGFsIDwtIHRvX2ZhY3RvcihBRURCJEhvc3BpdGFsKQp0YWJsZShhZS5nZW5kZXIsIGFlLmhvc3BpdGFsLCBkbm4gPSBjKCJTZXgiLCAiSG9zcGl0YWwiKSkKYWUuYXJ0ZXJ5IDwtIHRvX2ZhY3RvcihBRURCJEFydGVyeV9zdW1tYXJ5KQp0YWJsZShhZS5hcnRlcnksIGFlLmdlbmRlciwgZG5uID0gYygiU2V4IiwgIkFydGVyeSIpKQoKcm0oYWUuZ2VuZGVyLCBhZS5ob3NwaXRhbCwgYWUuYXJ0ZXJ5KQoKIyBJIGNoYW5nZSBudW1lcmljIGFuZCBmYWN0b3JzIG1hbnVhbGx5IGJlY2F1c2UsIHdlbGwsIEkgd291bGRuJ3Qga25vdyBob3cgdG8gZml4IGl0IG90aGVyd2lzZQojIHRvIGhhdmUgdGhpcyAndGliYmxlJyB3b3JrIHdpdGggJ3RhYmxlb25lJy4uLiA6LSkKCkFFREIkQWdlIDwtIGFzLm51bWVyaWMoQUVEQiRBZ2UpCkFFREIkZGlhc3RvbGkgPC0gYXMubnVtZXJpYyhBRURCJGRpYXN0b2xpKQpBRURCJHN5c3RvbGljIDwtIGFzLm51bWVyaWMoQUVEQiRzeXN0b2xpYykKCkFFREIkVENfZmluYWxDVSA8LSBhcy5udW1lcmljKEFFREIkVENfZmluYWxDVSkKQUVEQiRMRExfZmluYWxDVSA8LSBhcy5udW1lcmljKEFFREIkTERMX2ZpbmFsQ1UpCkFFREIkSERMX2ZpbmFsQ1UgPC0gYXMubnVtZXJpYyhBRURCJEhETF9maW5hbENVKQpBRURCJFRHX2ZpbmFsQ1UgPC0gYXMubnVtZXJpYyhBRURCJFRHX2ZpbmFsQ1UpCgpBRURCJFRDX2ZpbmFsIDwtIGFzLm51bWVyaWMoQUVEQiRUQ19maW5hbCkKQUVEQiRMRExfZmluYWwgPC0gYXMubnVtZXJpYyhBRURCJExETF9maW5hbCkKQUVEQiRIRExfZmluYWwgPC0gYXMubnVtZXJpYyhBRURCJEhETF9maW5hbCkKQUVEQiRUR19maW5hbCA8LSBhcy5udW1lcmljKEFFREIkVEdfZmluYWwpCgpBRURCJEFnZSA8LSBhcy5udW1lcmljKEFFREIkQWdlKQpBRURCJEdGUl9NRFJEIDwtIGFzLm51bWVyaWMoQUVEQiRHRlJfTURSRCkKQUVEQiRCTUkgPC0gYXMubnVtZXJpYyhBRURCJEJNSSkKQUVEQiRlQ2lnYXJldHRlcyA8LSBhcy5udW1lcmljKEFFREIkZUNpZ2FyZXR0ZXMpCkFFREIkZVBhY2tZZWFyc1Ntb2tpbmcgPC0gYXMubnVtZXJpYyhBRURCJGVQYWNrWWVhcnNTbW9raW5nKQpBRURCJEVQX2NvbXBvc2l0ZV90aW1lIDwtIGFzLm51bWVyaWMoQUVEQiRFUF9jb21wb3NpdGVfdGltZSkKQUVEQiRFUF9tYWpvcl90aW1lIDwtIGFzLm51bWVyaWMoQUVEQiRFUF9tYWpvcl90aW1lKQoKcmVxdWlyZShsYWJlbGxlZCkKQUVEQiRPUnllYXIgPC0gdG9fZmFjdG9yKEFFREIkT1J5ZWFyKQpBRURCJEdlbmRlciA8LSB0b19mYWN0b3IoQUVEQiRHZW5kZXIpCkFFREIkSG9zcGl0YWwgPC0gdG9fZmFjdG9yKEFFREIkSG9zcGl0YWwpCkFFREIkS0RPUUkgPC0gdG9fZmFjdG9yKEFFREIkS0RPUUkpCkFFREIkQk1JX1dITyA8LSB0b19mYWN0b3IoQUVEQiRCTUlfV0hPKQpBRURCJERpYWJldGVzU3RhdHVzIDwtIHRvX2ZhY3RvcihBRURCJERpYWJldGVzU3RhdHVzKQpBRURCJFNtb2tlclN0YXR1cyA8LSB0b19mYWN0b3IoQUVEQiRTbW9rZXJTdGF0dXMpCkFFREIkQWxjb2hvbFVzZSA8LSB0b19mYWN0b3IoQUVEQiRBbGNvaG9sVXNlKQoKQUVEQiRIeXBlcnRlbnNpb24uc2VsZnJlcG9ydCA8LSB0b19mYWN0b3IoQUVEQiRIeXBlcnRlbnNpb24xKQpBRURCJEh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1ZyA8LSB0b19mYWN0b3IoQUVEQiRIeXBlcnRlbnNpb24yKQpBRURCJEh5cGVydGVuc2lvbi5jb21wb3NpdGUgPC0gdG9fZmFjdG9yKEFFREIkSHlwZXJ0ZW5zaW9uLmNvbXBvc2l0ZSkKQUVEQiRIeXBlcnRlbnNpb24uZHJ1Z3MgPC0gdG9fZmFjdG9yKEFFREIkSHlwZXJ0ZW5zaW9uLmRydWdzKQoKQUVEQiRNZWQuYW50aWNvYWd1bGFudHMgPC0gdG9fZmFjdG9yKEFFREIkTWVkLmFudGljb2FndWxhbnRzKQpBRURCJE1lZC5hbGwuYW50aXBsYXRlbGV0IDwtIHRvX2ZhY3RvcihBRURCJE1lZC5hbGwuYW50aXBsYXRlbGV0KQpBRURCJE1lZC5TdGF0aW4uTExEIDwtIHRvX2ZhY3RvcihBRURCJE1lZC5TdGF0aW4uTExEKQoKQUVEQiRTdHJva2VfRHggPC0gdG9fZmFjdG9yKEFFREIkU3Ryb2tlX0R4KQpBRURCJENBRF9oaXN0b3J5IDwtIHRvX2ZhY3RvcihBRURCJENBRF9oaXN0b3J5KQpBRURCJFBBT0QgPC0gdG9fZmFjdG9yKEFFREIkUEFPRCkKQUVEQiRQZXJpcGhlcmFsLmludGVydiA8LSB0b19mYWN0b3IoQUVEQiRQZXJpcGhlcmFsLmludGVydikKCkFFREIkc3ltcHQgPC0gdG9fZmFjdG9yKEFFREIkc3ltcHQpCkFFREIkU3ltcHRvbXMuM2cgPC0gdG9fZmFjdG9yKEFFREIkU3ltcHRvbXMuM2cpCkFFREIkU3ltcHRvbXMuNGcgPC0gdG9fZmFjdG9yKEFFREIkU3ltcHRvbXMuNGcpCkFFREIkU3ltcHRvbXMuNUcgPC0gdG9fZmFjdG9yKEFFREIkU3ltcHRvbXMuNUcpCkFFREIkQXN5bXB0U3ltcHQgPC0gdG9fZmFjdG9yKEFFREIkQXN5bXB0U3ltcHQpCkFFREIkQXN5bXB0U3ltcHQyRyA8LSB0b19mYWN0b3IoQUVEQiRBc3ltcHRTeW1wdDJHKQoKQUVEQiRyZXN0ZW5vcyA8LSB0b19mYWN0b3IoQUVEQiRyZXN0ZW5vcykKQUVEQiRzdGVub3NlIDwtIHRvX2ZhY3RvcihBRURCJHN0ZW5vc2UpCkFFREIkRVBfY29tcG9zaXRlIDwtIHRvX2ZhY3RvcihBRURCJEVQX2NvbXBvc2l0ZSkKQUVEQiRFUF9tYWpvciA8LSB0b19mYWN0b3IoQUVEQiRFUF9tYWpvcikKQUVEQiRNYWNyb3BoYWdlcy5iaW4gPC0gdG9fZmFjdG9yKEFFREIkTWFjcm9waGFnZXMuYmluKQpBRURCJFNNQy5iaW4gPC0gdG9fZmFjdG9yKEFFREIkU01DLmJpbikKQUVEQiRJUEguYmluIDwtIHRvX2ZhY3RvcihBRURCJElQSC5iaW4pCkFFREIkQ2FsYy5iaW4gPC0gdG9fZmFjdG9yKEFFREIkQ2FsYy5iaW4pCkFFREIkQ29sbGFnZW4uYmluIDwtIHRvX2ZhY3RvcihBRURCJENvbGxhZ2VuLmJpbikKQUVEQiRGYXQuYmluXzEwIDwtIHRvX2ZhY3RvcihBRURCJEZhdC5iaW5fMTApCkFFREIkRmF0LmJpbl80MCA8LSB0b19mYWN0b3IoQUVEQiRGYXQuYmluXzQwKQpBRURCJE92ZXJhbGxQbGFxdWVQaGVub3R5cGUgPC0gdG9fZmFjdG9yKEFFREIkT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZSkKQUVEQiRQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA8LSB0b19mYWN0b3IoQUVEQiRQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCkKCkFFREIkQXJ0ZXJ5X3N1bW1hcnkgPC0gdG9fZmFjdG9yKEFFREIkQXJ0ZXJ5X3N1bW1hcnkpCgpBRURCJGluZm9ybWVkY29uc2VudCA8LSB0b19mYWN0b3IoQUVEQiRpbmZvcm1lZGNvbnNlbnQpCgpBRURCLkNFQSA8LSBzdWJzZXQoQUVEQiwKICAgICAgICAgICAgICAgICAgICAoQXJ0ZXJ5X3N1bW1hcnkgPT0gImNhcm90aWQgKGxlZnQgJiByaWdodCkiIHwgQXJ0ZXJ5X3N1bW1hcnkgPT0gIm90aGVyIGNhcm90aWQgYXJ0ZXJpZXMgKGNvbW1vbiwgZXh0ZXJuYWwpIikgJiAjIHdlIG9ubHkgd2FudCBjYXJvdGlkcwogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibWlzc2luZyIgJiAjIHdlIGFyZSByZWFsbHkgc3RyaWN0IGluIHNlbGVjdGluZyBiYXNlZCBvbiAnaW5mb3JtZWQgY29uc2VudCchCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgZGllZCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gaGVhbHRoIHRyZWF0bWVudCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRvZXNuJ3Qgd2FudCB0byIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHVuYWJsZSB0byBzaWduIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgbm8gcmVhY3Rpb24iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBsb3N0IiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgdG9vIG9sZCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyBtZWRpY2FsIGluZm8sIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8gKG5ldmVyIGFza2VkIGZvciBJQyBiZWNhdXNlIHRoZXJlIHdhcyBubyB0aXNzdWUpIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgZW5kcG9pbnQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vb2l0IGdlaW5jbHVkZWVyZCIgJiAKICAgICAgICAgICAgICAgICAgICAgIWlzLm5hKEFzeW1wdFN5bXB0MkcpKQojIEFFREIuQ0VBWzE6MTAsIDE6MTBdCmRpbShBRURCLkNFQSkKCkFFREIuZnVsbCA8LSBzdWJzZXQoQUVEQiwKICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm1pc3NpbmciICYgIyB3ZSBhcmUgcmVhbGx5IHN0cmljdCBpbiBzZWxlY3RpbmcgYmFzZWQgb24gJ2luZm9ybWVkIGNvbnNlbnQnIQogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRpZWQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGhlYWx0aCB0cmVhdG1lbnQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkb2Vzbid0IHdhbnQgdG8iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCB1bmFibGUgdG8gc2lnbiIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIG5vIHJlYWN0aW9uIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgbG9zdCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHRvbyBvbGQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gbWVkaWNhbCBpbmZvLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGVuZHBvaW50IiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJub29pdCBnZWluY2x1ZGVlcmQiKQojIEFFREIuQ0VBWzE6MTAsIDE6MTBdCmRpbShBRURCLmZ1bGwpCgpgYGAKCgpgYGB7ciBCYXNlbGluZSBBRURCOiBjcmVhdGlvbn0KY2F0KCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKQpjYXQoIkNSRUFURSBCQVNFTElORSBUQUJMRVxuIikKCiMgQmFzZWxpbmUgdGFibGUgdmFyaWFibGVzCmJhc2V0YWJsZV92YXJzID0gYygiSG9zcGl0YWwiLCAiT1J5ZWFyIiwKICAgICAgICAgICAgICAgICAgICJBZ2UiLCAiR2VuZGVyIiwgCiAgICAgICAgICAgICAgICAgICAjICJUQ19maW5hbENVIiwgIkxETF9maW5hbENVIiwgIkhETF9maW5hbENVIiwgIlRHX2ZpbmFsQ1UiLCAKICAgICAgICAgICAgICAgICAgICJUQ19maW5hbCIsICJMRExfZmluYWwiLCAiSERMX2ZpbmFsIiwgIlRHX2ZpbmFsIiwgCiAgICAgICAgICAgICAgICAgICAjICJoc0NSUF9wbGFzbWEiLAogICAgICAgICAgICAgICAgICAgInN5c3RvbGljIiwgImRpYXN0b2xpIiwgIkdGUl9NRFJEIiwgIkJNSSIsIAogICAgICAgICAgICAgICAgICAgIktET1FJIiwgIkJNSV9XSE8iLAogICAgICAgICAgICAgICAgICAgIlNtb2tlclN0YXR1cyIsICJBbGNvaG9sVXNlIiwKICAgICAgICAgICAgICAgICAgICJEaWFiZXRlc1N0YXR1cyIsIAogICAgICAgICAgICAgICAgICAgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0IiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1ZyIsICJIeXBlcnRlbnNpb24uY29tcG9zaXRlIiwgIkh5cGVydGVuc2lvbi5kcnVncyIsIAogICAgICAgICAgICAgICAgICAgIk1lZC5hbnRpY29hZ3VsYW50cyIsICJNZWQuYWxsLmFudGlwbGF0ZWxldCIsICJNZWQuU3RhdGluLkxMRCIsIAogICAgICAgICAgICAgICAgICAgIlN0cm9rZV9EeCIsICJzeW1wdCIsICJTeW1wdG9tcy41RyIsICJBc3ltcHRTeW1wdCIsICJBc3ltcHRTeW1wdDJHIiwKICAgICAgICAgICAgICAgICAgICJyZXN0ZW5vcyIsICJzdGVub3NlIiwKICAgICAgICAgICAgICAgICAgICJDQURfaGlzdG9yeSIsICJQQU9EIiwgIlBlcmlwaGVyYWwuaW50ZXJ2IiwgCiAgICAgICAgICAgICAgICAgICAiRVBfY29tcG9zaXRlIiwgIkVQX2NvbXBvc2l0ZV90aW1lIiwgIkVQX21ham9yIiwgIkVQX21ham9yX3RpbWUiLAogICAgICAgICAgICAgICAgICAgIk1BQ19yYW5rTm9ybSIsICJTTUNfcmFua05vcm0iLCAiTWFjcm9waGFnZXMuYmluIiwgIlNNQy5iaW4iLAogICAgICAgICAgICAgICAgICAgIk5ldXRyb3BoaWxzX3JhbmtOb3JtIiwgIk1hc3RDZWxsc19yYW5rTm9ybSIsCiAgICAgICAgICAgICAgICAgICAiSVBILmJpbiIsICJWZXNzZWxEZW5zaXR5X3JhbmtOb3JtIiwKICAgICAgICAgICAgICAgICAgICJDYWxjLmJpbiIsICJDb2xsYWdlbi5iaW4iLCAKICAgICAgICAgICAgICAgICAgICJGYXQuYmluXzEwIiwgIkZhdC5iaW5fNDAiLCAiT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZSIsICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIpCgpiYXNldGFibGVfYmluID0gYygiR2VuZGVyIiwgCiAgICAgICAgICAgICAgICAgICJLRE9RSSIsICJCTUlfV0hPIiwKICAgICAgICAgICAgICAgICAgIlNtb2tlclN0YXR1cyIsICJBbGNvaG9sVXNlIiwKICAgICAgICAgICAgICAgICAgIkRpYWJldGVzU3RhdHVzIiwgCiAgICAgICAgICAgICAgICAgICJIeXBlcnRlbnNpb24uc2VsZnJlcG9ydCIsICJIeXBlcnRlbnNpb24uc2VsZnJlcG9ydGRydWciLCAiSHlwZXJ0ZW5zaW9uLmNvbXBvc2l0ZSIsICJIeXBlcnRlbnNpb24uZHJ1Z3MiLCAKICAgICAgICAgICAgICAgICAgIk1lZC5hbnRpY29hZ3VsYW50cyIsICJNZWQuYWxsLmFudGlwbGF0ZWxldCIsICJNZWQuU3RhdGluLkxMRCIsIAogICAgICAgICAgICAgICAgICAiU3Ryb2tlX0R4IiwgInN5bXB0IiwgIlN5bXB0b21zLjVHIiwgIkFzeW1wdFN5bXB0IiwgIkFzeW1wdFN5bXB0MkciLAogICAgICAgICAgICAgICAgICAicmVzdGVub3MiLCAic3Rlbm9zZSIsCiAgICAgICAgICAgICAgICAgICJDQURfaGlzdG9yeSIsICJQQU9EIiwgIlBlcmlwaGVyYWwuaW50ZXJ2IiwgCiAgICAgICAgICAgICAgICAgICJFUF9jb21wb3NpdGUiLCAiTWFjcm9waGFnZXMuYmluIiwgIlNNQy5iaW4iLAogICAgICAgICAgICAgICAgICAiSVBILmJpbiIsIAogICAgICAgICAgICAgICAgICAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICJGYXQuYmluXzEwIiwgIkZhdC5iaW5fNDAiLCAiT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZSIsICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIpCiMgYmFzZXRhYmxlX2JpbgoKYmFzZXRhYmxlX2NvbiA9IGJhc2V0YWJsZV92YXJzWyFiYXNldGFibGVfdmFycyAlaW4lIGJhc2V0YWJsZV9iaW5dCiMgYmFzZXRhYmxlX2NvbgpgYGAKCiMjIyBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5OiBiYXNlbGluZSBjaGFyYWN0ZXJpc3RpY3MKU2hvd2luZyB0aGUgYmFzZWxpbmUgdGFibGUgb2YgdGhlIHdob2xlIEF0aGVyby1FeHByZXNzIEJpb2JhbmsuCgpgYGB7ciBCYXNlbGluZSBBRURCOiBWaXN1YWxpemUgQUVEQn0KIyBDcmVhdGUgYmFzZWxpbmUgdGFibGVzCiMgaHR0cDovL3JzdHVkaW8tcHVicy1zdGF0aWMuczMuYW1hem9uYXdzLmNvbS8xMzMyMV9kYTMxNDYzM2RiOTI0ZGM3ODk4NmE4NTA4MTNhNTBkNS5odG1sCkFFREIudGFibGVPbmUgPSBwcmludChDcmVhdGVUYWJsZU9uZSh2YXJzID0gYmFzZXRhYmxlX3ZhcnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgZmFjdG9yVmFycyA9IGJhc2V0YWJsZV9iaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzdHJhdGEgPSAiU3ltcHRvbXMuNGciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBBRURCLmZ1bGwsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjNdCmBgYAoKCmBgYHtyIEJhc2VsaW5lIEFFREI6IFZpc3VhbGl6ZSBBRURCIENFQX0KIyBDcmVhdGUgYmFzZWxpbmUgdGFibGVzCiMgaHR0cDovL3JzdHVkaW8tcHVicy1zdGF0aWMuczMuYW1hem9uYXdzLmNvbS8xMzMyMV9kYTMxNDYzM2RiOTI0ZGM3ODk4NmE4NTA4MTNhNTBkNS5odG1sCkFFREIuQ0VBLnRhYmxlT25lID0gcHJpbnQoQ3JlYXRlVGFibGVPbmUodmFycyA9IGJhc2V0YWJsZV92YXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZhY3RvclZhcnMgPSBiYXNldGFibGVfYmluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc3RyYXRhID0gIlN5bXB0b21zLjRnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gQUVEQi5DRUEsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjNdCmBgYAoKCgojIyBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeTogcHJlcGFyZQoKTGV0J3MgY29tYmluZSB0aGUgZnVsbCBBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5IHdpdGggdGhlIGtleS10YWJsZSBjb250YWluaW5nIHRoZSBBRUdTIGRhdGEuCgo+IE5PVEU6IHRoaXMgc2hvdWxkIHN1bSB0byAyLDEyNCBzYW1wbGVzIHdpdGggZ2Vub3R5cGVzLgoKYGBge3IgY3JlYXRlIEFFR1N9CkFFR1MgPC0gbWVyZ2UoQUVEQi5mdWxsLCBBRUdTMTIzLnNhbXBsZUxpc3Qua2V5dGFibGUsIGJ5LnggPSAiU1RVRFlfTlVNQkVSIiwgYnkueSA9ICJTVFVEWV9OVU1CRVIiLCBzb3J0ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgIGFsbCA9IFRSVUUpCgpkaW0oQUVHUykKCkFFR1MkVVBJRC55IDwtIE5VTEwKbmFtZXMoQUVHUylbbmFtZXMoQUVHUykgPT0gIlVQSUQueCJdIDwtICJVUElEIgpBRUdTJEFnZS55IDwtIE5VTEwKbmFtZXMoQUVHUylbbmFtZXMoQUVHUykgPT0gIkFnZS54Il0gPC0gIkFnZSIKCnRhYmxlKEFFR1MkQ0hJUCwgdXNlTkEgPSAiaWZhbnkiKQoKQUVHUyRHV0FTIDwtIEFFR1MkQ0hJUApBRUdTJEdXQVNbaXMubmEoQUVHUyRHV0FTKV0gPC0gIm5vdCBnZW5vdHlwZWQiCkFFR1MkR1dBU1tBRUdTJEdXQVMgIT0gIm5vdCBnZW5vdHlwZWQiXSA8LSAiZ2Vub3R5cGVkIgoKdGFibGUoQUVHUyRDSElQLCBBRUdTJEdXQVMsIHVzZU5BID0gImlmYW55IikKYGBgCgpBbHNvIGEgdmlzdWFsaXNhdGlvbiBvZiB0aGUgQUVHUyB3aXRoIEFFREIgb3ZlcmxhcHMuCmBgYHtyIHZpc3VhbGlzZSBBRUdTIG92ZXJsYXBzfQpsaWJyYXJ5KFVwU2V0UikKcmVxdWlyZShnZ3Bsb3QyKQpyZXF1aXJlKHBseXIpCnJlcXVpcmUoZ3JpZEV4dHJhKQpyZXF1aXJlKGdyaWQpCgpBRURCLmF2YWlsR1dBUyA9IGxpc3QoCkFFR1MxID0gc3Vic2V0KEFFR1MsIENISVAgPT0gIkFmZnlTTlA1Iiwgc2VsZWN0ID0gYygiU1RVRFlfTlVNQkVSIikpWywxXSwKQUVHUzIgPSBzdWJzZXQoQUVHUywgQ0hJUCA9PSAiQWZmeUF4aW9tQ0VVIiwgc2VsZWN0ID0gYygiU1RVRFlfTlVNQkVSIikpWywxXSwKQUVHUzMgPSBzdWJzZXQoQUVHUywgQ0hJUCA9PSAiSWxsR1NBIiwgc2VsZWN0ID0gYygiU1RVRFlfTlVNQkVSIikpWywxXSwKQUVEQiA9IEFFR1MkU1RVRFlfTlVNQkVSKQoKcDEgPC0gVXBTZXRSOjp1cHNldChmcm9tTGlzdChBRURCLmF2YWlsR1dBUyksIAogICAgICAgICAgICAgICAgICAgIHNldHMgPSBjKCJBRURCIiwgIkFFR1MxIiwgIkFFR1MyIiwgIkFFR1MzIiksIAogICAgICAgICAgICAgICAgICAgIG1haW4uYmFyLmNvbG9yID0gYyh1aXRob2ZfY29sb3JbMTVdLCB1aXRob2ZfY29sb3JbMl0sIHVpdGhvZl9jb2xvclszXSwgdWl0aG9mX2NvbG9yWzIxXSksIAogICAgICAgICAgICAgICAgICAgIG1haW5iYXIueS5sYWJlbAk9ICJpbnRlcnNlY3Rpb24gc2FtcGxlIHNpemUiLCAKICAgICAgICAgICAgICAgICAgICBzZXRzLmJhci5jb2xvciA9IGModWl0aG9mX2NvbG9yWzE1XSwgdWl0aG9mX2NvbG9yWzJdLCB1aXRob2ZfY29sb3JbM10sIHVpdGhvZl9jb2xvclsyMV0pLCAKICAgICAgICAgICAgICAgICAgICBzZXRzLngubGFiZWwgPSAic2FtcGxlIHNpemUiLCBrZWVwLm9yZGVyID0gVFJVRSkKcGRmKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5vdmVybGFwLkFFREJfQUVHUzEyMy5VcFNldFIucGRmIikpCiAgcDEKZGV2Lm9mZigpCnBuZyhwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIub3ZlcmxhcC5BRURCX0FFR1MxMjMuVXBTZXRSLnBuZyIpKQogIHAxCmRldi5vZmYoKQpwMQpybShwMSkKYGBgCgoKYGBge3IgU3BlY2lmaWNTZWxlY3Rpb259CnRhYmxlKEFFR1MkQXJ0ZXJ5X3N1bW1hcnksIEFFR1MkUUMyMDE4X0ZJTFRFUikKdGFibGUoQUVHUyRpbmZvcm1lZGNvbnNlbnQsIEFFR1MkUUMyMDE4X0ZJTFRFUikKQUVHU3NlbGVjdCA8LSBzdWJzZXQoQUVHUywgCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibWlzc2luZyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRpZWQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGhlYWx0aCB0cmVhdG1lbnQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkb2Vzbid0IHdhbnQgdG8iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCB1bmFibGUgdG8gc2lnbiIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIG5vIHJlYWN0aW9uIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgbG9zdCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHRvbyBvbGQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gbWVkaWNhbCBpbmZvLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGVuZHBvaW50IiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJub29pdCBnZWluY2x1ZGVlcmQiKQoKQUVHU3NlbGVjdC5DRUEgPC0gc3Vic2V0KEFFR1MsICFpcy5uYShRQzIwMThfRklMVEVSKSAmIFFDMjAxOF9GSUxURVIgIT0gImlzc3VlIiAmIFFDMjAxOF9GSUxURVIgIT0gImZhbWlseV9kaXNjYXJkIiAmCiAgICAgICAgICAgICAgICAgICAgIChBcnRlcnlfc3VtbWFyeSA9PSAiY2Fyb3RpZCAobGVmdCAmIHJpZ2h0KSIgfCBBcnRlcnlfc3VtbWFyeSA9PSAib3RoZXIgY2Fyb3RpZCBhcnRlcmllcyAoY29tbW9uLCBleHRlcm5hbCkiKSAmICMgd2Ugb25seSB3YW50IGNhcm90aWRzCiAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibWlzc2luZyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRpZWQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJpY2FsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIG1lZGljYWwgaW5mbywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGhlYWx0aCB0cmVhdG1lbnQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcyIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBkb2Vzbid0IHdhbnQgdG8iICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCB1bmFibGUgdG8gc2lnbiIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIG5vIHJlYWN0aW9uIiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgbG9zdCIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHRvbyBvbGQiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gbWVkaWNhbCBpbmZvLCBoZWFsdGggdHJlYXRtZW50IHdoZW4gcG9zc2libGUiICYKICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKSIgJgogICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGVuZHBvaW50IiAmCiAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJub29pdCBnZWluY2x1ZGVlcmQiKQoKZGltKEFFR1NzZWxlY3QpCgp0YWJsZShBRUdTc2VsZWN0JEFydGVyeV9zdW1tYXJ5LCBBRUdTc2VsZWN0JFFDMjAxOF9GSUxURVIpCnRhYmxlKEFFR1NzZWxlY3QkQXJ0ZXJ5X3N1bW1hcnksIEFFR1NzZWxlY3QkQ0hJUCkKdGFibGUoQUVHU3NlbGVjdCRRQzIwMThfRklMVEVSLCBBRUdTc2VsZWN0JENISVApCnRhYmxlKEFFR1NzZWxlY3QkUUMyMDE4X0ZJTFRFUiwgQUVHU3NlbGVjdCRTQU1QTEVfVFlQRSkKCkFFREIudGVtcCA8LSBzdWJzZXQoQUVHU3NlbGVjdCwgIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJVUElEIiwgIkFnZSIsICJHZW5kZXIiLCAiSG9zcGl0YWwiLCAiQXJ0ZXJ5X3N1bW1hcnkiLCAiUUMyMDE4X0ZJTFRFUiIsICJDSElQIiwgIlNBTVBMRV9UWVBFIikpCnJlcXVpcmUobGFiZWxsZWQpCkFFREIudGVtcCRHZW5kZXIgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRHZW5kZXIpCkFFREIudGVtcCRIb3NwaXRhbCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJEhvc3BpdGFsKQpBRURCLnRlbXAkQXJ0ZXJ5X3N1bW1hcnkgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRBcnRlcnlfc3VtbWFyeSkKQUVEQi50ZW1wJFFDMjAxOF9GSUxURVIgPC0gdG9fZmFjdG9yKEFFREIudGVtcCRRQzIwMThfRklMVEVSKQpBRURCLnRlbXAkQ0hJUCA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJENISVApCkFFREIudGVtcCRTQU1QTEVfVFlQRSA8LSB0b19mYWN0b3IoQUVEQi50ZW1wJFNBTVBMRV9UWVBFKQoKRFQ6OmRhdGF0YWJsZShBRURCLnRlbXBbMToxMCxdLCBjYXB0aW9uID0gIkV4Y2VycHQgb2YgdGhlIHdob2xlIEFFREIuIiwgcm93bmFtZXMgPSBGQUxTRSkKCnJtKEFFREIudGVtcCkKCgpgYGAKCiMjIEF0aGVyby1FeHByZXNzIEdlbm9taWNzIFN0dWR5OiBiYXNlbGluZSBjaGFyYWN0ZXJpc3RpY3MKClNob3dpbmcgdGhlIGJhc2VsaW5lIHRhYmxlIG9mIHRoZSBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeS4KCmBgYHtyIEJhc2VsaW5lIFNhbXBsZVNlbGVjdDogcHJlcGFyZX0KIyBDcmVhdGUgYmFzZWxpbmUgdGFibGVzCiMgaHR0cDovL3JzdHVkaW8tcHVicy1zdGF0aWMuczMuYW1hem9uYXdzLmNvbS8xMzMyMV9kYTMxNDYzM2RiOTI0ZGM3ODk4NmE4NTA4MTNhNTBkNS5odG1sCkFFR1NzZWxlY3QkR1dBUyA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdCRHV0FTKQpBRUdTc2VsZWN0JENISVAgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QkQ0hJUCkKQUVHU3NlbGVjdCRQQ0EgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QkUENBKQpBRUdTc2VsZWN0JFNBTVBMRV9UWVBFIDwtIHRvX2ZhY3RvcihBRUdTc2VsZWN0JFNBTVBMRV9UWVBFKQpBRUdTc2VsZWN0JGluZm9ybWVkY29uc2VudCA8LSB0b19mYWN0b3IoQUVHU3NlbGVjdCRpbmZvcm1lZGNvbnNlbnQpCgpBRUdTc2VsZWN0LkNFQSRHV0FTIDwtIHRvX2ZhY3RvcihBRUdTc2VsZWN0LkNFQSRHV0FTKQpBRUdTc2VsZWN0LkNFQSRDSElQIDwtIHRvX2ZhY3RvcihBRUdTc2VsZWN0LkNFQSRDSElQKQpBRUdTc2VsZWN0LkNFQSRQQ0EgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QuQ0VBJFBDQSkKQUVHU3NlbGVjdC5DRUEkU0FNUExFX1RZUEUgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QuQ0VBJFNBTVBMRV9UWVBFKQpBRUdTc2VsZWN0LkNFQSRpbmZvcm1lZGNvbnNlbnQgPC0gdG9fZmFjdG9yKEFFR1NzZWxlY3QuQ0VBJGluZm9ybWVkY29uc2VudCkKCgpjYXQoIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpCmNhdCgiQ1JFQVRFIEJBU0VMSU5FIFRBQkxFXG4iKQoKIyBCYXNlbGluZSB0YWJsZSB2YXJpYWJsZXMKYmFzZXRhYmxlX3ZhcnMgPSBjKCJIb3NwaXRhbCIsIAogICAgICAgICAgICAgICAgICAgIkFnZSIsICJHZW5kZXIiLCAKICAgICAgICAgICAgICAgICAgICJUQ19maW5hbCIsICJMRExfZmluYWwiLCAiSERMX2ZpbmFsIiwgIlRHX2ZpbmFsIiwgCiAgICAgICAgICAgICAgICAgICAic3lzdG9saWMiLCAiZGlhc3RvbGkiLCAiR0ZSX01EUkQiLCAiQk1JIiwgCiAgICAgICAgICAgICAgICAgICAiS0RPUUkiLCAiQk1JX1dITyIsIAogICAgICAgICAgICAgICAgICAgIlNtb2tlckN1cnJlbnQiLCAiZUNpZ2FyZXR0ZXMiLCAiZVBhY2tZZWFyc1Ntb2tpbmciLAogICAgICAgICAgICAgICAgICAgIkRpYWJldGVzU3RhdHVzIiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0IiwgIkh5cGVydGVuc2lvbi5zZWxmcmVwb3J0ZHJ1ZyIsICJIeXBlcnRlbnNpb24uY29tcG9zaXRlIiwgCiAgICAgICAgICAgICAgICAgICAiSHlwZXJ0ZW5zaW9uLmRydWdzIiwgIk1lZC5hbnRpY29hZ3VsYW50cyIsICJNZWQuYWxsLmFudGlwbGF0ZWxldCIsICJNZWQuU3RhdGluLkxMRCIsIAogICAgICAgICAgICAgICAgICAgIlN0cm9rZV9EeCIsICJzeW1wdCIsICJTeW1wdG9tcy41RyIsICJyZXN0ZW5vcyIsCiAgICAgICAgICAgICAgICAgICAiRVBfY29tcG9zaXRlIiwgIkVQX2NvbXBvc2l0ZV90aW1lIiwKICAgICAgICAgICAgICAgICAgICJtYWNtZWFuMCIsICJzbWNtZWFuMCIsICJNYWNyb3BoYWdlcy5iaW4iLCAiU01DLmJpbiIsICJuZXV0cm9waGlscyIsICJNYXN0X2NlbGxzX3BsYXF1ZSIsICJ2ZXNzZWxfZGVuc2l0eV9hdmVyYWdlZCIsCiAgICAgICAgICAgICAgICAgICAiSVBILmJpbiIsIAogICAgICAgICAgICAgICAgICAgIkNhbGMuYmluIiwgIkNvbGxhZ2VuLmJpbiIsIAogICAgICAgICAgICAgICAgICAgIkZhdC5iaW5fMTAiLCAiRmF0LmJpbl80MCIsICJPdmVyYWxsUGxhcXVlUGhlbm90eXBlIiwgIlBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4IiwKICAgICAgICAgICAgICAgICAgICJTTUNfcmFua05vcm0iLCAiTUFDX3JhbmtOb3JtIiwgIk5ldXRyb3BoaWxzX3JhbmtOb3JtIiwgIk1hc3RDZWxsc19yYW5rTm9ybSIsICJWZXNzZWxEZW5zaXR5X3JhbmtOb3JtIiwKICAgICAgICAgICAgICAgICAgIkdXQVMiLCAiQ0hJUCIsICJQQ0EiKQoKYmFzZXRhYmxlX2JpbiA9IGMoIkdlbmRlciIsIAogICAgICAgICAgICAgICAgICAiS0RPUUkiLCAiQk1JX1dITyIsIAogICAgICAgICAgICAgICAgICAiU21va2VyQ3VycmVudCIsIAogICAgICAgICAgICAgICAgICAiRGlhYmV0ZXNTdGF0dXMiLCAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnQiLCAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnRkcnVnIiwgIkh5cGVydGVuc2lvbi5jb21wb3NpdGUiLCAKICAgICAgICAgICAgICAgICAgIkh5cGVydGVuc2lvbi5kcnVncyIsICJNZWQuYW50aWNvYWd1bGFudHMiLCAiTWVkLmFsbC5hbnRpcGxhdGVsZXQiLCAiTWVkLlN0YXRpbi5MTEQiLCAKICAgICAgICAgICAgICAgICAgIlN0cm9rZV9EeCIsICJzeW1wdCIsICJTeW1wdG9tcy41RyIsICJyZXN0ZW5vcyIsCiAgICAgICAgICAgICAgICAgICJFUF9jb21wb3NpdGUiLCAiTWFjcm9waGFnZXMuYmluIiwgIlNNQy5iaW4iLAogICAgICAgICAgICAgICAgICAiSVBILmJpbiIsIAogICAgICAgICAgICAgICAgICAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICJGYXQuYmluXzEwIiwgIkZhdC5iaW5fNDAiLCAiT3ZlcmFsbFBsYXF1ZVBoZW5vdHlwZSIsICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIsCiAgICAgICAgICAgICAgICAgICJHV0FTIiwgIkNISVAiLCAiUENBIikKCmJhc2V0YWJsZV9iaW4KCmJhc2V0YWJsZV9jb24gPSBiYXNldGFibGVfdmFyc1shYmFzZXRhYmxlX3ZhcnMgJWluJSBiYXNldGFibGVfYmluXQpiYXNldGFibGVfY29uCgpgYGAKCkFsbCBBdGhlcm8tRXhwcmVzcyBHZW5vbWljcyBTdHVkeSBkYXRhIChuID0gMiwwMTEpLCBjb21wYXJlZCB0byB0aGUgX3JlbWFpbmluZ18sIF91bl9nZW5vdHlwZWQgQXRoZXJvLUV4cHJlc3MgQmlvYmFuayBTdHVkeS4KYGBge3IgQmFzZWxpbmUgU2FtcGxlU2VsZWN0OiBWaXN1YWxpemUsIHdob2xlfQpjYXQoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIikKY2F0KCJESVNQTEFZIEJBU0VMSU5FIFRBQkxFXG4iKQoKQUVHU3NlbGVjdC50YWJsZU9uZSA9IHByaW50KENyZWF0ZVRhYmxlT25lKHZhcnMgPSBiYXNldGFibGVfdmFycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmYWN0b3JWYXJzID0gYmFzZXRhYmxlX2JpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGEgPSAiR1dBUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEFFR1NzZWxlY3QsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjZdCmBgYAoKQmFzZWxpbmUgb2YgdGhlIHZhbGlkLCBDRUEgYW5kIGdlbm90eXBlZCBkYXRhLgpgYGB7ciBCYXNlbGluZSBTYW1wbGVTZWxlY3Q6IFZpc3VhbGl6ZSwgQ0VBfQpBRUdTc2VsZWN0LkNFQS50YWJsZU9uZSA9IHByaW50KENyZWF0ZVRhYmxlT25lKHZhcnMgPSBiYXNldGFibGVfdmFycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmYWN0b3JWYXJzID0gYmFzZXRhYmxlX2JpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhdGEgPSAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gQUVHU3NlbGVjdC5DRUEsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIG1pc3NpbmcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIG5vU3BhY2VzID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLCBleHBsYWluID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gInBmIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjZdCmBgYAoKIyMgQXRoZXJvLUV4cHJlc3MgR2Vub21pY3MgU3R1ZHk6IHdyaXRpbmcKCkxldCdzIHNhdmUgdGhlIGJhc2VsaW5lIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgQXRoZXJvLUV4cHJlc3MgR2Vub21pY3MgU3R1ZHkuCgpgYGB7ciBCYXNlbGluZSBTYW1wbGVTZWxlY3Rpb246IHdyaXRlfQojIFdyaXRlIGJhc2V0YWJsZQpyZXF1aXJlKG9wZW54bHN4KQoKd3JpdGUueGxzeChmaWxlID0gcGFzdGUwKEJBU0VMSU5FX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFR1MuQmFzZWxpbmVUYWJsZS54bHN4IiksIAogICAgICAgICAgIEFFR1NzZWxlY3QudGFibGVPbmUsIAogICAgICAgICAgIHJvd05hbWVzID0gVFJVRSwgCiAgICAgICAgICAgY29sTmFtZXMgPSBUUlVFLCAKICAgICAgICAgICBzaGVldE5hbWUgPSAiQUVHU19CYXNlbGluZSIsIG92ZXJ3cml0ZSA9IFRSVUUpCgp3cml0ZS54bHN4KGZpbGUgPSBwYXN0ZTAoQkFTRUxJTkVfbG9jLCAiLyIsVG9kYXksIi4iLFBST0pFQ1ROQU1FLCIuQUVHUy5DRUEuQmFzZWxpbmVUYWJsZS54bHN4IiksIAogICAgICAgICAgIEFFR1NzZWxlY3QuQ0VBLnRhYmxlT25lLCAKICAgICAgICAgICByb3dOYW1lcyA9IFRSVUUsIAogICAgICAgICAgIGNvbE5hbWVzID0gVFJVRSwgCiAgICAgICAgICAgc2hlZXROYW1lID0gIkFFR1NfQmFzZWxpbmVfZnVsbCIsIG92ZXJ3cml0ZSA9IFRSVUUpCmBgYAoKIyBTYW1wbGVMaXN0cwoKIyMgQXV0b3NvbWFsIGRhdGEuCgpXZSBhcmUgcmVhZHkgdG8gbWFrZSBhIHNhbXBsZUxpc3QgZm9yIHVzZSB3aXRoIHRoZSBpbXB1dGVkIGRhdGEuCgpgYGB7ciBQcmVwIFNhbXBsZVNlbGVjdH0KcmVxdWlyZShvcGVueGxzeCkKCnRlbXAgPC0gc3Vic2V0KEFFR1MsCiAgICAgICAgICAgICAgIEdXQVMgPT0gImdlbm90eXBlZCIsCiAgICAgICAgICAgICAgIHNlbGVjdCA9IGMoIklEXzEiLCAiSURfMiIsICJVUElEIiwgIlNUVURZX05VTUJFUiIsICMgSURfMiBpcyB0aGUgb3JkZXIgb2Ygc2FtcGxlcyEKICAgICAgICAgICAgICAgICAgICAgICAgICAiUUMyMDE4X0ZJTkFMIiwgIlFDMjAxOF9GSUxURVIiLCAiT3JpZ2luYWxPcmRlcl9wb3N0TWljaEltcF9RQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFR1NfdHlwZSIsICJDSElQIiwgIlNUVURZX1RZUEUiLCAiU0FNUExFX1RZUEUiLCAiUENBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDNiIsICJQQzciLCAiUEM4IiwgIlBDOSIsICJQQzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiU2V4IiwgIkFnZSIsICJPUnllYXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhdC5iaW5fMTAiLCAiRmF0LmJpbl80MCIsICJJUEguYmluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNNQ19yYW5rTm9ybSIsICJNQUNfcmFua05vcm0iLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIpKSAjIFNlbGVjdCBzb21lIHBoZW5vdHlwZSBvZiBpbnRlcmVzdApkaW0odGVtcCkKCiMgRml4IHRoaW5ncwphdHRhY2godGVtcCkKCnRlbXBbLCJDYWxjaWZpY2F0aW9uIl0gPC0gTkEKdGVtcCRDYWxjaWZpY2F0aW9uW0NhbGMuYmluID09ICJuby9taW5vciJdIDwtICJjb250cm9sIgp0ZW1wJENhbGNpZmljYXRpb25bQ2FsYy5iaW4gPT0gIm1vZGVyYXRlL2hlYXZ5Il0gPC0gImNhc2UiCgp0ZW1wWywiQ29sbGFnZW4iXSA8LSBOQQp0ZW1wJENvbGxhZ2VuW0NvbGxhZ2VuLmJpbiA9PSAibm8vbWlub3IiXSA8LSAiY29udHJvbCIKdGVtcCRDb2xsYWdlbltDb2xsYWdlbi5iaW4gPT0gIm1vZGVyYXRlL2hlYXZ5Il0gPC0gImNhc2UiCgp0ZW1wWywiRmF0MTAiXSA8LSBOQQp0ZW1wJEZhdDEwW0ZhdC5iaW5fMTAgPT0gIjwxMCUiXSA8LSAiY29udHJvbCIKdGVtcCRGYXQxMFtGYXQuYmluXzEwID09ICI+MTAlIl0gPC0gImNhc2UiCgp0ZW1wWywiRmF0NDAiXSA8LSBOQQp0ZW1wJEZhdDQwW0ZhdC5iaW5fNDAgPT0gIjw0MCUiXSA8LSAiY29udHJvbCIKdGVtcCRGYXQ0MFtGYXQuYmluXzQwID09ICI+NDAlIl0gPC0gImNhc2UiCgp0ZW1wWywiSVBIIl0gPC0gTkEKdGVtcCRJUEhbSVBILmJpbiA9PSAibm8iXSA8LSAiY29udHJvbCIKdGVtcCRJUEhbSVBILmJpbiA9PSAieWVzIl0gPC0gImNhc2UiCgp0ZW1wWywiUFZJIl0gPC0gTkEKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjAiXSA8LSAiUFZJX2NhdDAiCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICIxIl0gPC0gIlBWSV9jYXQxIgp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiMiJdIDwtICJQVklfY2F0MiIKdGVtcCRQVklbUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPT0gIjMiXSA8LSAiUFZJX2NhdDMiCnRlbXAkUFZJW1BsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4ID09ICI0Il0gPC0gIlBWSV9jYXQ0Igp0ZW1wJFBWSVtQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9PSAiNSJdIDwtICJQVklfY2F0NSIKCnRlbXAkUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXggPC0gdGVtcCRQVkkKdGVtcCRQVkkgPC0gTlVMTAoKZGV0YWNoKHRlbXApCgojIE1ha2luZyBzZWxlY3Rpb24gdmFyaWFibGUKYXR0YWNoKHRlbXApCnRlbXBbLCJTRUxFQ1RJT04iXSA8LSAibm90X3NlbGVjdGVkIgp0ZW1wJFNFTEVDVElPTlsoUUMyMDE4X0ZJTFRFUj09InBhc3NlZCIgfCBRQzIwMThfRklMVEVSPT0iZmFtaWx5X2tlZXAiKSAmIChTVFVEWV9UWVBFPT0iQ0VBIiAmIFBDQT09IkVVUiIpXSA8LSAic2VsZWN0ZWQiCmRldGFjaCh0ZW1wKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRRQzIwMThfRklMVEVSKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRTVFVEWV9UWVBFKQp0YWJsZSh0ZW1wJFNFTEVDVElPTiwgdGVtcCRQQ0EpCnRhYmxlKHRlbXAkUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgpCgpgYGAKCgpgYGB7ciBTYXZlIFNhbXBsZVNlbGVjdH0KCkFFR1MxMjNfc2FtcGxlLmxpc3QgPC0gdGVtcFtvcmRlcih0ZW1wJE9yaWdpbmFsT3JkZXJfcG9zdE1pY2hJbXBfUUMpLF0KCkFFR1MxMjNfc2FtcGxlLmxpc3QkbWlzc2luZyA8LSAwCgpzYW1wbGVfZmlsZV9hZWdzIDwtIGRwbHlyOjpzZWxlY3QoQUVHUzEyM19zYW1wbGUubGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEXzEsIElEXzIsIG1pc3NpbmcsICMgSURfMiBpcyB0aGUgb3JkZXIgb2Ygc2FtcGxlcyAtIHRoYXQgd2F5IHdlIGFsd2F5cyBrbm93IHdoYXQgdGhlIG9yZGVyIHNob3VsZCBiZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVBJRCwgU1RVRFlfTlVNQkVSLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFDMjAxOF9GSU5BTCwgUUMyMDE4X0ZJTFRFUiwgU0VMRUNUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUVHU190eXBlLCBDSElQLCBTVFVEWV9UWVBFLCBTQU1QTEVfVFlQRSwgUENBLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEMxLCBQQzIsIFBDMywgUEM0LCBQQzUsIFBDNiwgUEM3LCBQQzgsIFBDOSwgUEMxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNleCwgQWdlLCBPUnllYXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2FsY2lmaWNhdGlvbiwgQ29sbGFnZW4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmF0MTAsIEZhdDQwLCBJUEgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU01DX3JhbmtOb3JtLCBNQUNfcmFua05vcm0sIE5ldXRyb3BoaWxzX3JhbmtOb3JtLCBNYXN0Q2VsbHNfcmFua05vcm0sIFZlc3NlbERlbnNpdHlfcmFua05vcm0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCkgICU+JQogIG11dGF0ZV9pZihpcy5udW1lcmljLCBhcy5jaGFyYWN0ZXIpICU+JQogIG11dGF0ZShTQU1QTEVfVFlQRSA9IGdzdWIoJyAnLCAnXycsIFNBTVBMRV9UWVBFKSkgJT4lCiAgYWRkX3JvdyguYmVmb3JlID0gMSwgCiAgICAgICAgICBJRF8xID0gIjAiLCBJRF8yID0gIjAiLCBtaXNzaW5nID0gIjAiLCAKICAgICAgICAgIFVQSUQgPSAiRCIsIFNUVURZX05VTUJFUiA9ICJDIiwKICAgICAgICAgIFFDMjAxOF9GSU5BTCA9ICJEIiwgUUMyMDE4X0ZJTFRFUiA9ICJEIiwgU0VMRUNUSU9OID0gIkQiLAogICAgICAgICAgQUVHU190eXBlID0gIkQiLCBDSElQID0gIkQiLCBTVFVEWV9UWVBFID0gIkQiLCBTQU1QTEVfVFlQRSA9ICJEIiwgUENBID0gIkQiLAogICAgICAgICAgUEMxID0gIkMiLCBQQzIgPSAiQyIsIFBDMyA9ICJDIiwgUEM0ID0gIkMiLCBQQzUgPSAiQyIsIFBDNiA9ICJDIiwgUEM3ID0gIkMiLCBQQzggPSAiQyIsIFBDOSA9ICJDIiwgUEMxMCA9ICJDIiwKICAgICAgICAgIFNleCA9ICJEIiwgQWdlID0gIkMiLCBPUnllYXIgPSAiQyIsIAogICAgICAgICAgQ2FsY2lmaWNhdGlvbiA9ICJCIiwgQ29sbGFnZW4gPSAiQiIsIAogICAgICAgICAgRmF0MTAgPSAiQiIsIEZhdDQwID0gIkIiLCBJUEggPSAiQiIsIAogICAgICAgICAgU01DX3JhbmtOb3JtID0gIlAiLCBNQUNfcmFua05vcm0gPSAiUCIsIE5ldXRyb3BoaWxzX3JhbmtOb3JtID0gIlAiLCBNYXN0Q2VsbHNfcmFua05vcm0gPSAiUCIsIFZlc3NlbERlbnNpdHlfcmFua05vcm0gPSAiUCIsCiAgICAgICAgICBQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCA9ICJQIikgJT4lICMjIGlkZW50aWZpZXJzOiBpbmRleCBmb3IgdGhlc2UgaXMgMSwgYW5kIGFsbCBiYXNlIHZhcmlhYmxlcyBoYXZlIDAgYXMgaWRlbnRpZmllcgogIHByaW50KCkKZGltKHNhbXBsZV9maWxlX2FlZ3MpCgpmd3JpdGUoc2FtcGxlX2ZpbGVfYWVncywKICAgICAgIGZpbGUgPSBwYXN0ZTAoU05QX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFR1MxMjMuc2FtcGxlIiksCiAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsCiAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSwKICAgICAgIHNob3dQcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQoKcmVxdWlyZShEVCkKRFQ6OmRhdGF0YWJsZShzYW1wbGVfZmlsZV9hZWdzLCBjYXB0aW9uID0gIkFFR1M6IGZpbmFsIHNhbXBsZSBsaXN0IG9mIGdlbm90eXBlZCBBRSBwYXRpZW50cyBhZnRlciBxdWFsaXR5IGNvbnRyb2wuIiwgcm93bmFtZXMgPSBGQUxTRSkKCnJtKHRlbXAsIHRlbXAyLCB0ZW1wMykKYGBgCgojIyBYLWNocm9tb3NvbWUgZGF0YQoKVGhlIFgtY2hyb21vc29tZSBkYXRhIGlzIHRha2VuIGZyb20gcHJldmlvdXNseSBpbXB1dGVkIGRhdGEgYmFzZWQgb24gMTAwMEcgcGhhc2UgMyAodmVyc2lvbiA1KSBhbmQgR29OTDUuIEZvciBzb21lIHJlYXNvbiwgaW1wdXRpbmcgb24gdGhlIE1pY2hpZ2FuIEltcHV0YXRpb24gU2VydmVyIHdhcyBub3Qgc3VjY2Vzc2Z1bCAoKkFDVElPTiBwb2ludCopLgoKSGVyZSB3ZSBsb2FkIGluIHRoZSBzYW1wbGUgZmlsZXMgZm9yIHRoZSB0aHJlZSBkYXRhc2V0cyBvZiB0aGUgWCBjaHJvbW9zb21hbCBkYXRhLiBXZSBzaG91bGQ6CgotIGZpbHRlciBvdXQgc2FtcGxlcyB0aGF0IGRpZCBub3QgcGFzcyBxdWFsaXR5IGNvbnRyb2wsIGVuZGluZyB1cCB3aXRoIDIsMTI0IHNhbXBsZQotIHJlLW9yZGVyIHRoZSBkYXRhIHRvIGZpdCB0aGUgb3RoZXIgYXV0b3NvbWFsIGRhdGEuCgoKYGBge3IgU2FtcGxlTGlzdCBYfQoKQUVHUzEyM19jaHJYIDwtIGZyZWFkKHBhc3RlMChNSUNISU1QX2xvYywgIi9fY2hyMjNfMWtnX2dvbmw1L2FlZ3MucmF3LjFrZ19nb25sNS5jaHIyMy5tYXBwaW5ncy50eHQiKSkKbmFtZXMoQUVHUzEyM19jaHJYKVtuYW1lcyhBRUdTMTIzX2NoclgpID09ICJJRF8xIl0gPC0gIlNhbXBsZUlEX3Bvc3RJbXBDaHJYIgoKQUVHUzEyM19BbGxDaHIgPC0gbWVyZ2UoQUVHUzEyM19jaHJYLCBzYW1wbGVfZmlsZV9hZWdzLCBieS54ID0gIlNhbXBsZUlEX3Bvc3RNaWNoSW1wIiwgYnkueSA9ICJJRF8xIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGFsbC54ID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHNvcnQgPSBGQUxTRSkKCm5hbWVzKEFFR1MxMjNfQWxsQ2hyKVtuYW1lcyhBRUdTMTIzX0FsbENocikgPT0gIklEXzIueSJdIDwtICJJRF8yIgpuYW1lcyhBRUdTMTIzX0FsbENocilbbmFtZXMoQUVHUzEyM19BbGxDaHIpID09ICJTVFVEWV9UWVBFLnkiXSA8LSAiU1RVRFlfVFlQRSIKbmFtZXMoQUVHUzEyM19BbGxDaHIpW25hbWVzKEFFR1MxMjNfQWxsQ2hyKSA9PSAiU2FtcGxlSURfcG9zdE1pY2hJbXAiXSA8LSAiSURfMSIKQUVHUzEyM19BbGxDaHIkbWlzc2luZy54IDwtIE5VTEwKQUVHUzEyM19BbGxDaHIkbWlzc2luZy55IDwtIE5VTEwKQUVHUzEyM19BbGxDaHIkU1RVRFlfVFlQRS54IDwtIE5VTEwKQUVHUzEyM19BbGxDaHIkSURfMi54IDwtIE5VTEwKCmRpbShBRUdTMTIzX0FsbENocikKc3RyKEFFR1MxMjNfQWxsQ2hyKQpgYGAKClRoaXMgc2VlbXMgZmluZSwgbGV0J3MgZmlsdGVyOyB3ZSBjYW4gdXNlIHRoaXMgZmlsZSB0byBmaWx0ZXIgdGhlIGdlbmV0aWMgZGF0YS4gQW5kIHdlIGNyZWF0ZSBhbm90aGVyIGZpbGUgdG8gcmUtb3JkZXIgdGhlIGRhdGEuCgpgYGB7ciBTYW1wbGVMaXN0IFg6IGZpbHRlcn0KCkFFR1MxMjNfQWxsQ2hyUUMgPC0gc3Vic2V0KEFFR1MxMjNfQWxsQ2hyLAogICAgICAgICAgICAgICAhaXMubmEoUUMyMDE4X0ZJTFRFUiksCiAgICAgICAgICAgICAgIHNlbGVjdCA9IGMoIklEXzEiLCAiSURfMiIsICJVUElEIiwgIlNUVURZX05VTUJFUiIsICJTYW1wbGVJRF9wb3N0SW1wQ2hyWCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlFDMjAxOF9GSU5BTCIsICJRQzIwMThfRklMVEVSIiwgIlNFTEVDVElPTiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkFFR1NfdHlwZSIsICJDSElQIiwgIlNUVURZX1RZUEUiLCAiU0FNUExFX1RZUEUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQQzEiLCAiUEMyIiwgIlBDMyIsICJQQzQiLCAiUEM1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUEM2IiwgIlBDNyIsICJQQzgiLCAiUEM5IiwgIlBDMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJTZXgiLCAiQWdlIiwgIk9SeWVhciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICJDYWxjaWZpY2F0aW9uIiwgIkNvbGxhZ2VuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhdDEwIiwgIkZhdDQwIiwgIklQSCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICJTTUNfcmFua05vcm0iLCAiTUFDX3JhbmtOb3JtIiwgIk5ldXRyb3BoaWxzX3JhbmtOb3JtIiwgIk1hc3RDZWxsc19yYW5rTm9ybSIsICJWZXNzZWxEZW5zaXR5X3JhbmtOb3JtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgiKSkKCkFFR1MxMjNfQWxsQ2hyUUNfcmVvcmRlciA8LUFFR1MxMjNfQWxsQ2hyUUNbb3JkZXIoQUVHUzEyM19BbGxDaHJRQyRJRF8yKSxdICMgcmVtZW1iZXI6IElEXzIgaXMgdGhlIG9yZGVyIG9mIHNhbXBsZXMKCkFFR1MxMjNfQWxsQ2hyUUNfZmlsdGVyZWQgPC0gc3Vic2V0KEFFR1MxMjNfQWxsQ2hyLAogICAgICAgICAgICAgICBpcy5uYShRQzIwMThfRklMVEVSKSwKICAgICAgICAgICAgICAgc2VsZWN0ID0gYygiSURfMSIsICJJRF8yIiwgIlVQSUQiLCAiU1RVRFlfTlVNQkVSIiwgIlNhbXBsZUlEX3Bvc3RJbXBDaHJYIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiUUMyMDE4X0ZJTkFMIiwgIlFDMjAxOF9GSUxURVIiLCAiU0VMRUNUSU9OIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQUVHU190eXBlIiwgIkNISVAiLCAiU1RVRFlfVFlQRSIsICJTQU1QTEVfVFlQRSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlBDMSIsICJQQzIiLCAiUEMzIiwgIlBDNCIsICJQQzUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQQzYiLCAiUEM3IiwgIlBDOCIsICJQQzkiLCAiUEMxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNleCIsICJBZ2UiLCAiT1J5ZWFyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbGNpZmljYXRpb24iLCAiQ29sbGFnZW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiRmF0MTAiLCAiRmF0NDAiLCAiSVBIIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNNQ19yYW5rTm9ybSIsICJNQUNfcmFua05vcm0iLCAiTmV1dHJvcGhpbHNfcmFua05vcm0iLCAiTWFzdENlbGxzX3JhbmtOb3JtIiwgIlZlc3NlbERlbnNpdHlfcmFua05vcm0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIpKQoKZndyaXRlKEFFR1MxMjNfQWxsQ2hyUUNfcmVvcmRlciwKICAgICAgIGZpbGUgPSBwYXN0ZTAoU05QX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFR1MxMjMuY2hyWC5zYW1wbGUiKSwKICAgICAgIG5hID0gIk5BIiwgc2VwID0gIlx0IiwgcXVvdGUgPSBGQUxTRSwKICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFLAogICAgICAgc2hvd1Byb2dyZXNzID0gVFJVRSwgdmVyYm9zZSA9IFRSVUUpCgpyZXF1aXJlKERUKQpEVDo6ZGF0YXRhYmxlKEFFR1MxMjNfQWxsQ2hyUUMsIGNhcHRpb24gPSAiQUVHUzogZmluYWwgc2FtcGxlIGxpc3Qgb2YgZ2Vub3R5cGVkIEFFIHBhdGllbnRzIGFmdGVyIHF1YWxpdHkgY29udHJvbCAoY2hyb21vc29tZSBYKS4iLCByb3duYW1lcyA9IEZBTFNFKQoKCmBgYAoKIyBHV0FTVG9vbEtpdCBwcmVwYXJhdGlvbgoKIyMgVmFyaWFudExpc3RzOiB0b3AgU05QcwoKSGVyZSB3ZSBjcmVhdGUgYSBgdmFyaWFudGxpc3QudHh0YCBmaWxlIHVzZWQgYnkgKipHV0FTVG9vbEtpdCoqIGZvciBhbmFseXNpcy5UaGVzZSBhcmUgdGhlIHZhcmlhbnRzIHdpdGggTEQgcjxzdXA+Mjwvc3VwPiA9PiAwLjYgYXJvdW5kIGVhY2ggb2YgdGhlIDE1IHRvcCBTTlBzIGFzc29jaWF0ZWQgd2l0aCBDQUMuCgpgYGB7ciBjcmVhdGUgdmFyaWFudExpc3R9CnZhcmlhbnRfbGlzdAoKdGVtcCA8LSBzdWJzZXQodmFyaWFudF9saXN0LCBzZWxlY3QgPSBjKCJWYXJpYW50SUQiLCAiQ2hyIiwgIkJQIikpCgpmd3JpdGUodGVtcCwKICAgICAgIGZpbGUgPSBwYXN0ZTAoU05QX2xvYywgIi92YXJpYW50bGlzdC50eHQiKSwKICAgICAgIG5hID0gIk5BIiwgc2VwID0gIlx0IiwgcXVvdGUgPSBGQUxTRSwKICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBGQUxTRSwKICAgICAgIHNob3dQcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFKQpybSh0ZW1wKQpgYGAKIyMgVmFyaWFudExpc3RzOiBDcmVkaWJsZSBTZXQKCkhlcmUgd2UgY3JlYXRlIGEgYGNyZWRpYmxlc2V0bGlzdC50eHRgIGZpbGUgdXNlZCBieSAqKkdXQVNUb29sS2l0KiogZm9yIGFuYWx5c2lzLlRoZXNlIGFyZSB0aGUgdmFyaWFudHMgaW4gdGhlIDk1JSBjcmVkaWJsZSBzZXQgb2YgY2F1c2FsIHZhcmlhbnRzIGZvciB0aGUgMTUgdG9wIFNOUHMgYXNzb2NpYXRlZCB3aXRoIENBQy4KCmBgYHtyIGNyZWF0ZSBjcmVkc2V0X2xpc3R9CmNyZWRzZXRfbGlzdAoKdGVtcCA8LSBzdWJzZXQoY3JlZHNldF9saXN0LCBzZWxlY3QgPSBjKCJWYXJpYW50SUQiLCAiQ2hyIiwgIkJQIikpCgpmd3JpdGUodGVtcCwKICAgICAgIGZpbGUgPSBwYXN0ZTAoU05QX2xvYywgIi9jcmVkaWJsZXNldGxpc3QudHh0IiksCiAgICAgICBuYSA9ICJOQSIsIHNlcCA9ICJcdCIsIHF1b3RlID0gRkFMU0UsCiAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gRkFMU0UsCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSkKcm0odGVtcCkKYGBgCgojIyBDb3ZhcmlhdGVzCgpIZXJlIHdlIGNyZWF0ZSBhIGBjb3ZhcmlhdGVzLnR4dGAgZmlsZSB1c2VkIGJ5ICoqR1dBU1Rvb2xLaXQqKiBmb3IgYW5hbHlzaXMuCgpgYGB7ciBjcmVhdGUgY292YXJpYXRlc0xpc3R9CmxpYnJhcnkodGlkeXZlcnNlKQojIGZvciAnb3ZlcmFsbCcgYW5hbHlzZXMKYygiQWdlIFNleCBQQzEgUEMyIENISVAgT1J5ZWFyIikgJT4lIHdyaXRlX2xpbmVzKHBhc3RlMChTTlBfbG9jLCAiL2NvdmFyaWF0ZXMudHh0IikpCgojIGZvciBzZXgtc3BlY2lmaWMgYW5hbHlzZXMKYygiQWdlIFBDMSBQQzIgQ0hJUCBPUnllYXIiKSAlPiUgd3JpdGVfbGluZXMocGFzdGUwKFNOUF9sb2MsICIvY292YXJpYXRlcy5zZXgudHh0IikpCmBgYAoKIyMgUGhlbm90eXBlcwoKSGVyZSB3ZSBjcmVhdGUgYSBgcGhlbm90eXBlcy50eHRgIGZpbGUgdXNlZCBieSAqKkdXQVNUb29sS2l0KiogZm9yIGFuYWx5c2lzLgoKYGBge3IgY3JlYXRlIHBoZW5vdHlwZXNMaXN0fQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYygiQ2FsY2lmaWNhdGlvbiIsICJDb2xsYWdlbiIsICJGYXQxMCIsICJGYXQ0MCIsICJJUEgiLCAiU01DX3JhbmtOb3JtIiwgIk1BQ19yYW5rTm9ybSIsICJOZXV0cm9waGlsc19yYW5rTm9ybSIsICJNYXN0Q2VsbHNfcmFua05vcm0iLCAiVmVzc2VsRGVuc2l0eV9yYW5rTm9ybSIsCiAgIlBsYXF1ZV9WdWxuZXJhYmlsaXR5X0luZGV4IikgJT4lIHdyaXRlX2xpbmVzKHBhc3RlMChTTlBfbG9jLCAiL3BoZW5vdHlwZXMudHh0IikpCgpjKCJQbGFxdWVfVnVsbmVyYWJpbGl0eV9JbmRleCIpICU+JSB3cml0ZV9saW5lcyhwYXN0ZTAoU05QX2xvYywgIi9waGVub3R5cGVzLnB2aS50eHQiKSkKCgpgYGAKCgojIFNlc3Npb24gaW5mb3JtYXRpb24KCi0tLS0tLQoKICAgIFZlcnNpb246ICAgICAgdjEuMC42CiAgICBMYXN0IHVwZGF0ZTogIDIwMjEtMTItMDMKICAgIFdyaXR0ZW4gYnk6ICAgU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiAocy53LnZhbmRlcmxhYW4tMlthdF11bWN1dHJlY2h0Lm5sKS4KICAgIERlc2NyaXB0aW9uOiAgU2NyaXB0IHRvIGdldCBzb21lIEF0aGVyby1FeHByZXNzIEJpb2JhbmsgU3R1ZHkgYmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzLgogICAgTWluaW11bSByZXF1aXJlbWVudHM6IFIgdmVyc2lvbiAzLjQuMyAoMjAxNy0wNi0zMCkgLS0gJ1NpbmdsZSBDYW5kbGUnLCBNYWMgT1MgWCBFbCBDYXBpdGFuCiAgICAKICAgIENoYW5nZXMgbG9nCiAgICAqIHYxLjAuNiBVcGRhdGUgY29kZSBhbmQgZml4IGNvZGluZyBvZiBwbGFxdWUgdnVsbmVyYWJpbGl0eSBpbmRleCAoUFZJKSB0byB3b3JrIHdpdGggU05QVEVTVC4KICAgICogdjEuMC41IFVwZGF0ZSBhbmFseXNpcyB3aXRoIGNyZWRpYmxlIHNldCBTTlBzLgogICAgKiB2MS4wLjQgVXBkYXRlIHdpdGggUFZJLiBSZW1vdmVkIFBDU0s5LgogICAgKiB2MS4wLjMgVXBkYXRlIHRvIHRoZSBnZW5lIGxpc3QuCiAgICAqIHYxLjAuMiBVcGRhdGVkIGJhc2VsaW5lIGNoYXJhY3RlcmlzdGljcyBpbmZvcm1hdGlvbi4gVXBkYXRlIEdXQVNUb29sS2l0IHByZXBhcmF0aW9uLiBBZGRlZCBtb3JlIGNhbmRpZGF0ZSBTTlBzIHRvIGxvb2sgYXQuIFVwZGF0ZWQgc29tZSB2YXJpYWJsZSBuYW1lcy4gCiAgICAqIHYxLjAuMSBBZGQgYW4gYWRkaXRpb25hbCBwaGVub3R5cGUuCiAgICAqIHYxLjAuMCBJbml0aWFsIHZlcnNpb24uIEZpeGVkIGJhc2VsaW5lIHRhYmxlLCBhZGRlZCBjb2RlcywgYW5kIHJlc3VsdHMuIENyZWF0ZWQgc2FtcGxlLWZpbGVzLgoKCgotLS0tLS0KCmBgYHtyIGV2YWwgPSBUUlVFfQpzZXNzaW9uSW5mbygpCmBgYAoKCiMgU2F2aW5nIGVudmlyb25tZW50CmBgYHtyIFNhdmluZ30Kc2F2ZS5pbWFnZShwYXN0ZTAoUFJPSkVDVF9sb2MsICIvIixUb2RheSwiLiIsUFJPSkVDVE5BTUUsIi5yZXN1bHRzLlJEYXRhIikpCmBgYAoKCi0tLS0tLQo8c3VwPiZjb3B5OyAxOTc5LTIwMjEgU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiB8IHMudy52YW5kZXJsYWFuW2F0XWdtYWlsLmNvbSB8IFtzd3ZhbmRlcmxhYW4uZ2l0aHViLmlvXShodHRwczovL3N3dmFuZGVybGFhbi5naXRodWIuaW8pLjwvc3VwPgotLS0tLS0KCiAgCiAgCiAgCgoK